From: richardbarry Date: Mon, 17 Oct 2011 13:17:58 +0000 (+0000) Subject: First commit with TriCore port and demo - still a work in progress. X-Git-Tag: V7.1.0~39 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1092b86956810f392a9fe81934afb801af51d6d3;p=freertos First commit with TriCore port and demo - still a work in progress. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1621 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/Source/portable/GCC/TriCore_1782/MPU_Wrappers.c b/Source/portable/GCC/TriCore_1782/MPU_Wrappers.c new file mode 100644 index 000000000..178cd57cc --- /dev/null +++ b/Source/portable/GCC/TriCore_1782/MPU_Wrappers.c @@ -0,0 +1,604 @@ +/* + FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if configUSE_MPU == 1 + +/* Function for raising the privilege of a task. */ +extern portBASE_TYPE xPortRaisePrivilege( void ); + +/* + * Prototypes for all the MPU wrappers. + */ +signed portBASE_TYPE MPU_xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ); +void MPU_vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const xRegions ); +void MPU_vTaskDelete( xTaskHandle pxTaskToDelete ); +void MPU_vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ); +void MPU_vTaskDelay( portTickType xTicksToDelay ); +unsigned portBASE_TYPE MPU_uxTaskPriorityGet( xTaskHandle pxTask ); +void MPU_vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ); +void MPU_vTaskSuspend( xTaskHandle pxTaskToSuspend ); +signed portBASE_TYPE MPU_xTaskIsTaskSuspended( xTaskHandle xTask ); +void MPU_vTaskResume( xTaskHandle pxTaskToResume ); +void MPU_vTaskSuspendAll( void ); +signed portBASE_TYPE MPU_xTaskResumeAll( void ); +portTickType MPU_xTaskGetTickCount( void ); +unsigned portBASE_TYPE MPU_uxTaskGetNumberOfTasks( void ); +void MPU_vTaskList( signed char *pcWriteBuffer ); +void MPU_vTaskGetRunTimeStats( signed char *pcWriteBuffer ); +void MPU_vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ); +unsigned long MPU_ulTaskEndTrace( void ); +void MPU_vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue ); +pdTASK_HOOK_CODE MPU_xTaskGetApplicationTaskTag( xTaskHandle xTask ); +portBASE_TYPE MPU_xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ); +unsigned portBASE_TYPE MPU_uxTaskGetStackHighWaterMark( xTaskHandle xTask ); +xTaskHandle MPU_xTaskGetCurrentTaskHandle( void ); +portBASE_TYPE MPU_xTaskGetSchedulerState( void ); +xQueueHandle MPU_xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ); +signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); +unsigned portBASE_TYPE MPU_uxQueueMessagesWaiting( const xQueueHandle pxQueue ); +signed portBASE_TYPE MPU_xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ); +xQueueHandle MPU_xQueueCreateMutex( void ); +xQueueHandle MPU_xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ); +portBASE_TYPE MPU_xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ); +portBASE_TYPE MPU_xQueueGiveMutexRecursive( xQueueHandle xMutex ); +signed portBASE_TYPE MPU_xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); +signed portBASE_TYPE MPU_xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ); +void MPU_vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ); +void *MPU_pvPortMalloc( size_t xSize ); +void MPU_vPortFree( void *pv ); +void MPU_vPortInitialiseBlocks( void ); +size_t MPU_xPortGetFreeHeapSize( void ); +/*---------------------------------------------------------------------------*/ + +signed portBASE_TYPE MPU_xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) +{ +signed portBASE_TYPE xReturn; +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGenericCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, puxStackBuffer, xRegions ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const xRegions ) +{ +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskAllocateMPURegions( xTask, xRegions ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + void MPU_vTaskDelete( xTaskHandle pxTaskToDelete ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelete( pxTaskToDelete ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + void MPU_vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + void MPU_vTaskDelay( portTickType xTicksToDelay ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelay( xTicksToDelay ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + unsigned portBASE_TYPE MPU_uxTaskPriorityGet( xTaskHandle pxTask ) + { + unsigned portBASE_TYPE uxReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskPriorityGet( pxTask ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + void MPU_vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskPrioritySet( pxTask, uxNewPriority ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskSuspend( xTaskHandle pxTaskToSuspend ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspend( pxTaskToSuspend ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + signed portBASE_TYPE MPU_xTaskIsTaskSuspended( xTaskHandle xTask ) + { + signed portBASE_TYPE xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskIsTaskSuspended( xTask ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskResume( xTaskHandle pxTaskToResume ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskResume( pxTaskToResume ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSuspendAll( void ) +{ +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspendAll(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE MPU_xTaskResumeAll( void ) +{ +signed portBASE_TYPE xReturn; +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskResumeAll(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +portTickType MPU_xTaskGetTickCount( void ) +{ +portTickType xReturn; +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetTickCount(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE MPU_uxTaskGetNumberOfTasks( void ) +{ +unsigned portBASE_TYPE uxReturn; +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetNumberOfTasks(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + void MPU_vTaskList( signed char *pcWriteBuffer ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskList( pcWriteBuffer ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + void MPU_vTaskGetRunTimeStats( signed char *pcWriteBuffer ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetRunTimeStats( pcWriteBuffer ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + void MPU_vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskStartTrace( pcBuffer, ulBufferSize ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + unsigned long MPU_ulTaskEndTrace( void ) + { + unsigned long ulReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + ulReturn = ulTaskEndTrace(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return ulReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void MPU_vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + pdTASK_HOOK_CODE MPU_xTaskGetApplicationTaskTag( xTaskHandle xTask ) + { + pdTASK_HOOK_CODE xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetApplicationTaskTag( xTask ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + portBASE_TYPE MPU_xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) + { + portBASE_TYPE xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + unsigned portBASE_TYPE MPU_uxTaskGetStackHighWaterMark( xTaskHandle xTask ) + { + unsigned portBASE_TYPE uxReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) + xTaskHandle MPU_xTaskGetCurrentTaskHandle( void ) + { + xTaskHandle xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetCurrentTaskHandle(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + portBASE_TYPE MPU_xTaskGetSchedulerState( void ) + { + portBASE_TYPE xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetSchedulerState(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskEnterCritical( void ) +{ +extern void vTaskEnterCritical( void ); +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskEnterCritical(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void MPU_vTaskExitCritical( void ) +{ +extern void vTaskExitCritical( void ); +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vTaskExitCritical(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +xQueueHandle MPU_xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) +{ +xQueueHandle xReturn; +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreate( uxQueueLength, uxItemSize ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) +{ +signed portBASE_TYPE xReturn; +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE MPU_uxQueueMessagesWaiting( const xQueueHandle pxQueue ) +{ +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); +unsigned portBASE_TYPE uxReturn; + + uxReturn = uxQueueMessagesWaiting( pxQueue ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE MPU_xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) +{ +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); +signed portBASE_TYPE xReturn; + + xReturn = xQueueGenericReceive( pxQueue, pvBuffer, xTicksToWait, xJustPeeking ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + xQueueHandle MPU_xQueueCreateMutex( void ) + { + xQueueHandle xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutex(); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_COUNTING_SEMAPHORES == 1 + xQueueHandle MPU_xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) + { + xQueueHandle xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = (xQueueHandle) xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + portBASE_TYPE MPU_xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) + { + portBASE_TYPE xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + portBASE_TYPE MPU_xQueueGiveMutexRecursive( xQueueHandle xMutex ) + { + portBASE_TYPE xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGiveMutexRecursive( xMutex ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_ALTERNATIVE_API == 1 + signed portBASE_TYPE MPU_xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) + { + signed portBASE_TYPE xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = signed portBASE_TYPE xQueueAltGenericSend( pxQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_ALTERNATIVE_API == 1 + signed portBASE_TYPE MPU_xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) + { + signed portBASE_TYPE xReturn; + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueAltGenericReceive( pxQueue, pvBuffer, xTicksToWait, xJustPeeking ); + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ) + { + portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vQueueAddToRegistry( xQueue, pcName ); + + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +void *MPU_pvPortMalloc( size_t xSize ) +{ +void *pvReturn; +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvPortMalloc( xSize ); + + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vPortFree( void *pv ) +{ +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vPortFree( pv ); + + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + /* This just exists to keep the linker quiet. */ +extern unsigned long _lc_ub_heap[]; /* Heap */ +extern unsigned long _lc_ue_heap[]; /* Heap end */ + return (size_t)( _lc_ue_heap - _lc_ub_heap ); +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +void MPU_vPortInitialiseBlocks( void ) +{ +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + vPortInitialiseBlocks(); + + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xPortGetFreeHeapSize( void ) +{ +size_t xReturn; +portBASE_TYPE xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xPortGetFreeHeapSize(); + + portMPU_RESTORE_PRIORITY( xRunningPrivileged ); + + return xReturn; +} + +#endif /* configUSE_MPU */ diff --git a/Source/portable/GCC/TriCore_1782/port.c b/Source/portable/GCC/TriCore_1782/port.c new file mode 100644 index 000000000..eadcc0170 --- /dev/null +++ b/Source/portable/GCC/TriCore_1782/port.c @@ -0,0 +1,388 @@ +/* + FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* Standard includes. */ +#include +#include +#include +#include +#include +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "list.h" +/*-----------------------------------------------------------*/ + +/* System register Definitions. */ +#define portSYSTEM_PROGRAM_STATUS_WORD ( (unsigned portBASE_TYPE) 0x000008FF ) /* Supervisor Mode, MPU Register Set 0 and Call Depth Counting disabled. */ +#define portINITIAL_PRIVILEGED_PROGRAM_STATUS_WORD ( (unsigned portBASE_TYPE) 0x000014FF ) /* IO Level 1, MPU Register Set 1 and Call Depth Counting disabled. */ +#define portINITIAL_UNPRIVILEGED_PROGRAM_STATUS_WORD ( (unsigned portBASE_TYPE) 0x000010FF ) /* IO Level 0, MPU Register Set 1 and Call Depth Counting disabled. */ +#define portINITIAL_PCXI_UPPER_CONTEXT_WORD ( (unsigned portBASE_TYPE) 0x00C00000 ) /* The lower 20 bits identify the CSA address. */ +#define portINITIAL_PCXI_LOWER_CONTEXT_WORD ( (unsigned portBASE_TYPE) 0x00000000 ) /* The lower 20 bits identify the CSA address. */ +#define portUPPER_CONTEXT_BIT ( (unsigned portBASE_TYPE) 0x00400000 ) /* Bit that indicates whether the context is upper or lower. */ + +#define portINITIAL_SYSCON ( (unsigned portBASE_TYPE) 0x00000000 ) /* MPU Disable. */ + +#define portSELECT_PROGRAM_STATUS_WORD( xRunPrivileged ) ( ( xRunPrivileged ) ? portINITIAL_PRIVILEGED_PROGRAM_STATUS_WORD : portINITIAL_UNPRIVILEGED_PROGRAM_STATUS_WORD ) + +/* CSA manipulation macros. */ +#define portCSA_FCX_MASK ( 0x000FFFFFUL ) + +/* OS Interrupt and Trap mechanisms. */ +#define portRESTORE_PSW_MASK ( ~( 0x000000FFUL ) ) +#define portSYSCALL_TRAP 6 +#define portCCPN_MASK ( 0x000000FFUL ) + +#define portSYSTEM_DATA_PRIVILEGES ( 0xC0C0C0C0UL ) +#define portSYSTEM_CODE_PRIVILEGES ( 0x00008080UL ) + +#define portSYSTEM_PRIVILEGE_PROGRAM_STATUS_WORD ( (unsigned portBASE_TYPE) 0x00000800 ) /* Supervisor Mode. */ +/*-----------------------------------------------------------*/ + +#if configCHECK_FOR_STACK_OVERFLOW > 0 + #error "pxTopOfStack is used to store the last used CSA so it is not appropriate to enable stack checking." + /* The stack pointer is accessible using portCSA_TO_ADDRESS( portCSA_TO_ADDRESS( pxCurrentTCB->pxTopOfStack )[ 0 ] )[ 2 ]; */ +#endif /* configCHECK_FOR_STACK_OVERFLOW */ +/*-----------------------------------------------------------*/ + +/* + * This reference is required by the Save/Restore Context Macros. + */ +extern volatile unsigned portBASE_TYPE * pxCurrentTCB; +/*-----------------------------------------------------------*/ + +/* + * Perform any hardware configuration necessary to generate the tick interrupt. + */ +void vPortSystemTickHandler( int ) __attribute__((longcall)); +static void prvSetupTimerInterrupt( void ); +/*-----------------------------------------------------------*/ + +/* + * The Yield Handler and Syscalls when using the MPU build. + */ +void vPortYield( int iTrapIdentification ); +/*-----------------------------------------------------------*/ + +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +{ +unsigned portBASE_TYPE *pxUpperCSA = NULL; +unsigned portBASE_TYPE *pxLowerCSA = NULL; + + /* 16 Address Registers (4 Address registers are global) and 16 Data Registers. */ + /* 3 System Registers */ + + /* There are 3 registers that track the CSAs. */ + /* FCX points to the head of globally free set of CSAs. + * PCX for the task needs to point to Lower->Upper->NULL arrangement. + * LCX points to the last free CSA so that corrective action can be taken. + */ + + /* Need two CSAs to store the context of a task. + * The upper context contains D8-D15, A10-A15, PSW and PCXI->NULL. + * The lower context contains D0-D7, A2-A7, A11 and PCXI->UpperContext. + * The pxCurrentTCB->pxTopOfStack points to the Lower Context RSLCX matching the initial BISR. + * The Lower Context points to the Upper Context ready for the ready return from the interrupt handler. + * The Real stack pointer for the task is stored in the A10 which is restored with the upper context. + */ + + /* Have to disable interrupts here because we are manipulating the CSAs. */ + portENTER_CRITICAL(); + { + /* DSync to ensure that buffering is not a problem. */ + _dsync(); + + /* Consume two Free CSAs. */ + pxLowerCSA = portCSA_TO_ADDRESS( _mfcr( $FCX ) ); + if ( NULL != pxLowerCSA ) + { + /* The Lower Links to the Upper. */ + pxUpperCSA = portCSA_TO_ADDRESS( pxLowerCSA[ 0 ] ); + } + + /* Check that we have successfully reserved two CSAs. */ + if ( ( NULL != pxLowerCSA ) && ( NULL != pxUpperCSA ) ) + { + /* Remove the two consumed CSAs from the Free List. */ + _mtcr( $FCX, pxUpperCSA[ 0 ] ); + /* ISync to commit the change to the FCX. */ + _isync(); + } + else + { + /* For the time being, simply trigger a context list depletion trap. */ + _svlcx(); + } + } + portEXIT_CRITICAL(); + + /* Clear the CSA. */ + memset( pxUpperCSA, 0, 16 * sizeof( unsigned portBASE_TYPE ) ); + + /* Upper Context. */ + pxUpperCSA[ 2 ] = (unsigned portBASE_TYPE)pxTopOfStack; /* A10; Stack Return aka Stack Pointer */ + pxUpperCSA[ 1 ] = portSELECT_PROGRAM_STATUS_WORD( pdTRUE ); /* PSW */ + + /* Clear the CSA. */ + memset( pxLowerCSA, 0, 16 * sizeof( unsigned portBASE_TYPE ) ); + + /* Lower Context. */ + pxLowerCSA[ 8 ] = (unsigned portBASE_TYPE)pvParameters; /* A4; Address Type Parameter Register */ + pxLowerCSA[ 1 ] = (unsigned portBASE_TYPE)pxCode; /* A11; Return Address aka RA */ + /* PCXI pointing to the Upper context. */ + pxLowerCSA[ 0 ] = ( portINITIAL_PCXI_UPPER_CONTEXT_WORD | (unsigned portBASE_TYPE)portADDRESS_TO_CSA( pxUpperCSA ) ); + + /* Save the link to the CSA in the Top of Stack. */ + pxTopOfStack = (unsigned portBASE_TYPE *)portADDRESS_TO_CSA( pxLowerCSA ); + + /* DSync to ensure that buffering is not a problem. */ + _dsync(); + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xPortStartScheduler( void ) +{ +unsigned portBASE_TYPE uxMFCR = 0UL; +unsigned portBASE_TYPE *pxUpperCSA = NULL; +unsigned portBASE_TYPE *pxLowerCSA = NULL; + /* Set-up the timer interrupt. */ + prvSetupTimerInterrupt(); + + /* Install the Trap Handlers. */ +extern void vTrapInstallHandlers( void ); + vTrapInstallHandlers(); + + /* Install the Syscall Handler. */ + if ( 0 == _install_trap_handler( portSYSCALL_TRAP, vPortYield ) ) + { + /* Failed to install the Yield handler. */ + _debug(); + } + + /* Load the initial SYSCON. */ + _dsync(); + _mtcr( $SYSCON, portINITIAL_SYSCON ); + + /* ENDINIT has already been applied in the 'cstart.c' code. */ + + /* Set-up the Task switching ISR. */ + CPU_SRC0.reg = 0x00001001UL; + + /* Clear the PSW.CDC to enable RFE */ + uxMFCR = _mfcr( $PSW ); + uxMFCR &= portRESTORE_PSW_MASK; + _mtcr( $PSW, uxMFCR ); + + /* Finally, perform the equivalent of a portRESTORE_CONTEXT() */ + pxLowerCSA = portCSA_TO_ADDRESS( *(unsigned portBASE_TYPE *)pxCurrentTCB ); + pxUpperCSA = portCSA_TO_ADDRESS( pxLowerCSA[0] ); + _mtcr( $PCXI, *pxCurrentTCB ); + + _dsync(); + _nop(); + _rslcx(); + _nop(); + __asm volatile( "rfe" ); + + /* Will not get here. */ + return 0; +} +/*-----------------------------------------------------------*/ + +static void prvSetupTimerInterrupt( void ) +{ + /* Set-up the clock divider. */ + unlock_wdtcon(); + while ( 0 != ( WDT_CON0.reg & 0x1UL ) ); + /* RMC == 1 so STM Clock == FPI */ + STM_CLC.reg = ( 1UL << 8 ); + lock_wdtcon(); + + /* Set-up the Compare value. */ + STM_CMCON.reg = ( 31UL - __CLZ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) ); + /* Take into account the current time so a tick doesn't happen immediately. */ + STM_CMP0.reg = ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) + STM_TIM0.reg; + + if ( 0 != _install_int_handler( portKERNEL_INTERRUPT_PRIORITY_LEVEL, vPortSystemTickHandler, 0 ) ) + { + /* Set-up the interrupt. */ + STM_SRC0.reg = ( portKERNEL_INTERRUPT_PRIORITY_LEVEL | 0x00005000UL ); + + /* Enable the Interrupt. */ + STM_ISRR.reg = 0x1UL; + STM_ICR.reg = 0x1UL; + } + else + { + /* Failed to install the Tick Interrupt. */ + _debug(); + } +} +/*-----------------------------------------------------------*/ + +void vPortSystemTickHandler( int iArg ) +{ + /* Clear the interrupt source. */ + STM_ISRR.reg = 1UL; + /* Reload the Compare Match register for X ticks into the future. */ + STM_CMP0.reg += ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ); + + /* Kernel API calls require Critical Sections. */ + portINTERRUPT_ENTER_CRITICAL(); + { + /* Increment the Tick. */ + vTaskIncrementTick(); + } + portINTERRUPT_EXIT_CRITICAL(); + +#if configUSE_PREEMPTION == 1 + portYIELD_FROM_ISR( pdTRUE ); +#endif + + (void)iArg; +} +/*-----------------------------------------------------------*/ + +/* + * When a task is deleted, it is yielded permanently until the IDLE task + * has an opportunity to reclaim the memory that that task was using. + * Typically, the memory used by a task is the TCB and Stack but in the + * TriCore this includes the CSAs that were consumed as part of the Call + * Stack. These CSAs can only be returned to the Globally Free Pool when + * they are not part of the current Call Stack, hence, delaying the + * reclamation until the IDLE task is freeing the task's other resources. + * This function uses the head of the linked list of CSAs (from when the + * task yielded for the last time) and finds the tail (the very bottom of + * the call stack) and inserts this list at the head of the Free list, + * attaching the existing Free List to the tail of the reclaimed call stack. + * + * NOTE: the IDLE task needs processing time to complete this function + * and in heavily loaded systems, the Free CSAs may be consumed faster + * than they can be freed assuming that tasks are being spawned and + * deleted frequently. + */ +void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB ) +{ +unsigned portBASE_TYPE pxHeadCSA, pxTailCSA, pxFreeCSA; + + /* The first element in a TCB is the Last Used CSA. + * These simply need to be free'd to add them back to + * the global pool of CSAs. + */ + + /* Lookup the first element from the TCB. */ + pxHeadCSA = ( *pxTCB ) & portCSA_FCX_MASK; + + /* If there is something to reclaim. */ + if ( 0UL != ( pxHeadCSA & portCSA_FCX_MASK ) ) + { + /* Iterate over the CSAs that were consumed as part of the task. */ + pxTailCSA = pxHeadCSA; + while ( 0UL != ( portCSA_TO_ADDRESS( pxTailCSA )[ 0 ] & portCSA_FCX_MASK ) ) + { + /* Clear any extra bits from the link words. */ + portCSA_TO_ADDRESS( pxTailCSA )[ 0 ] = pxTailCSA & portCSA_FCX_MASK; + + /* Iterate to the next CSA. */ + pxTailCSA = portCSA_TO_ADDRESS( pxTailCSA )[ 0 ]; + } + + /* pxHeadCSA points to the first in the chain + * pxNextCSA points to the Head or the last in the chain. + */ + + portENTER_CRITICAL(); + { + /* Look up the current free CSA. */ + _dsync(); + pxFreeCSA = _mfcr( $FCX ); + + /* Join the current Free onto the Tail of what is being reclaimed. */ + portCSA_TO_ADDRESS( pxTailCSA )[ 0 ] = pxFreeCSA; + + /* Move the head of the reclaimed into the Free. */ + _dsync(); + _mtcr( $FCX, pxHeadCSA ); + /* ISync to commit the change to the FCX. */ + _isync(); + } + portEXIT_CRITICAL(); + } +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Nothing to do. Unlikely to want to end. */ +} +/*-----------------------------------------------------------*/ + +void vPortYield( int iTrapIdentification ) +{ + switch ( iTrapIdentification ) + { + case portSYSCALL_TASK_YIELD: + /* Select another task to run. */ + portYIELD_FROM_ISR( pdTRUE ); + break; + + default: + _debug(); + break; + } +} +/*-----------------------------------------------------------*/ diff --git a/Source/portable/GCC/TriCore_1782/portmacro.h b/Source/portable/GCC/TriCore_1782/portmacro.h new file mode 100644 index 000000000..17f20e698 --- /dev/null +++ b/Source/portable/GCC/TriCore_1782/portmacro.h @@ -0,0 +1,194 @@ +/* + FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* System Includes. */ +#include +#include + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE unsigned long +#define portBASE_TYPE long + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef unsigned portSHORT portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned portLONG portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*---------------------------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 4 +#define portNOP() __asm volatile( " nop " ) +#define portCRITICAL_NESTING_IN_TCB 1 +#define portRESTORE_FIRST_TASK_PRIORITY_LEVEL 1 +#define portKERNEL_INTERRUPT_PRIORITY_LEVEL 4 +#define portSYSTEM_INTERRUPT_PRIORITY_LEVEL 64 +/*---------------------------------------------------------------------------*/ + +typedef struct MPU_SETTINGS { unsigned long ulNotUsed; } xMPU_SETTINGS; + +/* Define away the instruction from the Restore Context Macro. */ +#define portPRIVILEGE_BIT 0x0UL + +extern void vTaskEnterCritical( void ); +extern void vTaskExitCritical( void ); +#define portENTER_CRITICAL() vTaskEnterCritical() +#define portEXIT_CRITICAL() vTaskExitCritical() +/*---------------------------------------------------------------------------*/ + +/* Task utilities. */ + +extern void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB ); + +/* CSA Manipulation. */ +#define portCSA_TO_ADDRESS( pCSA ) ( ( unsigned portBASE_TYPE * )( ( ( ( pCSA ) & 0x000F0000 ) << 12 ) | ( ( ( pCSA ) & 0x0000FFFF ) << 6 ) ) ) +#define portADDRESS_TO_CSA( pAddress ) ( ( unsigned portBASE_TYPE )( ( ( ( (unsigned portBASE_TYPE)( pAddress ) ) & 0xF0000000 ) >> 12 ) | ( ( (unsigned portBASE_TYPE)( pAddress ) & 0x003FFFC0 ) >> 6 ) ) ) +/*---------------------------------------------------------------------------*/ + +#define portYIELD() _syscall(0) +/* Port Restore is implicit in the platform when the function is returned from the original PSW is automatically replaced. */ +#define portSYSCALL_TASK_YIELD 0 +#define portSYSCALL_RAISE_PRIORITY 1 +/*---------------------------------------------------------------------------*/ + +/* Critical section management. */ + +/* Clear the ICR.IE bit. */ /* Or set ICR.CCPN to portSYSTEM_INTERRUPT_PRIORITY_LEVEL */ +#define portDISABLE_INTERRUPTS() _disable() +/* Set the ICR.IE bit. */ /* Or set ICR.CCPN to 0 */ +#define portENABLE_INTERRUPTS() _enable() + +#define portINTERRUPT_ENTER_CRITICAL() _disable() +#define portINTERRUPT_EXIT_CRITICAL() _enable() + +/*---------------------------------------------------------------------------*/ + +/* + * Save the context of a task. + * The upper context is automatically saved when entering a trap or interrupt. + * Need to save the lower context as well and copy the PCXI CSA ID into + * pxCurrentTCB->pxTopOfStack. Only Lower Context CSA IDs may be saved to the + * TCB of a task. + * + * Call vTaskSwitchContext to select the next task, note that this changes the + * value of pxCurrentTCB so that it needs to be reloaded. + * + * Call vPortSetMPURegisterSetOne to change the MPU mapping for the task + * that has just been switched in. + * + * Load the context of the task. + * Need to restore the lower context by loading the CSA from + * pxCurrentTCB->pxTopOfStack into PCXI (effectively changing the call stack). + * In the Interrupt handler post-amble, RSLCX will restore the lower context + * of the task. RFE will restore the upper context of the task, jump to the + * return address and restore the previous state of interrupts being + * enabled/disabled. + */ +#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) \ +{ \ +unsigned portBASE_TYPE *pxUpperCSA = NULL; \ +unsigned portBASE_TYPE xUpperCSA = 0UL; \ + if ( pdTRUE == xHigherPriorityTaskWoken ) \ + { \ + /*_disable();*/ \ + portINTERRUPT_ENTER_CRITICAL(); \ + _isync(); \ + xUpperCSA = _mfcr( $PCXI ); \ + pxUpperCSA = portCSA_TO_ADDRESS( xUpperCSA ); \ + *pxCurrentTCB = pxUpperCSA[0]; \ + vTaskSwitchContext(); \ + pxUpperCSA[0] = *pxCurrentTCB; \ + _dsync(); \ + _isync(); \ + _nop(); \ + _nop(); \ + } \ +} +/*---------------------------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ diff --git a/Source/portable/GCC/TriCore_1782/porttrap.c b/Source/portable/GCC/TriCore_1782/porttrap.c new file mode 100644 index 000000000..b1b8c7f3b --- /dev/null +++ b/Source/portable/GCC/TriCore_1782/porttrap.c @@ -0,0 +1,294 @@ +/* + FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* Kernel includes. */ +#include "FreeRTOS.h" + +/* Machine includes */ +#include +#include +#include +/*---------------------------------------------------------------------------*/ + +/* + * This reference is required by the Save/Restore Context Macros. + */ +extern volatile unsigned portBASE_TYPE * pxCurrentTCB; +/*-----------------------------------------------------------*/ + +/* + * This file contains base definitions for all of the possible traps in the system. + * It is suggested to provide implementations for all of the traps but for + * the time being they simply trigger a DEBUG instruction so that it is easy + * to see what caused a particular trap. + * + * Trap Class 6, the SYSCALL, is used exclusively by the operating system. + */ + +/* The Trap Classes. */ +#define portMMU_TRAP 0 +#define portIPT_TRAP 1 +#define portIE_TRAP 2 +#define portCM_TRAP 3 +#define portSBP_TRAP 4 +#define portASSERT_TRAP 5 +#define portNMI_TRAP 7 + +/* MMU Trap Identifications. */ +#define portTIN_MMU_VIRTUAL_ADDRESS_FILL 0 +#define portTIN_MMU_VIRTUAL_ADDRESS_PROTECTION 1 + +/* Internal Protection Trap Identifications. */ +#define portTIN_IPT_PRIVILIGED_INSTRUCTION 1 +#define portTIN_IPT_MEMORY_PROTECTION_READ 2 +#define portTIN_IPT_MEMORY_PROTECTION_WRITE 3 +#define portTIN_IPT_MEMORY_PROTECTION_EXECUTION 4 +#define portTIN_IPT_MEMORY_PROTECTION_PERIPHERAL_ACCESS 5 +#define portTIN_IPT_MEMORY_PROTECTION_NULL_ADDRESS 6 +#define portTIN_IPT_MEMORY_PROTECTION_GLOBAL_REGISTER_WRITE_PROTECTION 7 + +/* Instruction Error Trap Identifications. */ +#define portTIN_IE_ILLEGAL_OPCODE 1 +#define portTIN_IE_UNIMPLEMENTED_OPCODE 2 +#define portTIN_IE_INVALID_OPERAND 3 +#define portTIN_IE_DATA_ADDRESS_ALIGNMENT 4 +#define portTIN_IE_INVALID_LOCAL_MEMORY_ADDRESS 5 + +/* Context Management Trap Identifications. */ +#define portTIN_CM_FREE_CONTEXT_LIST_DEPLETION 1 +#define portTIN_CM_CALL_DEPTH_OVERFLOW 2 +#define portTIN_CM_CALL_DEPTH_UNDEFLOW 3 +#define portTIN_CM_FREE_CONTEXT_LIST_UNDERFLOW 4 +#define portTIN_CM_CALL_STACK_UNDERFLOW 5 +#define portTIN_CM_CONTEXT_TYPE 6 +#define portTIN_CM_NESTING_ERROR 7 + +/* System Bus and Peripherals Trap Identifications. */ +#define portTIN_SBP_PROGRAM_FETCH_SYNCHRONOUS_ERROR 1 +#define portTIN_SBP_DATA_ACCESS_SYNCHRONOUS_ERROR 2 +#define portTIN_SBP_DATA_ACCESS_ASYNCHRONOUS_ERROR 3 +#define portTIN_SBP_COPROCESSOR_TRAP_ASYNCHRONOUS_ERROR 4 +#define portTIN_SBP_PROGRAM_MEMORY_INTEGRITY_ERROR 5 +#define portTIN_SBP_DATA_MEMORY_INTEGRITY_ERROR 6 + +/* Assertion Trap Identifications. */ +#define portTIN_ASSERT_ARITHMETIC_OVERFLOW 1 +#define portTIN_ASSERT_STICKY_ARITHMETIC_OVERFLOW 2 + +/* Non-maskable Interrupt Trap Identifications. */ +#define portTIN_NMI_NON_MASKABLE_INTERRUPT 0 +/*---------------------------------------------------------------------------*/ + +void vMMUTrap( int iTrapIdentification ); +void vInternalProtectionTrap( int iTrapIdentification ); +void vInstructionErrorTrap( int iTrapIdentification ); +void vContextManagementTrap( int iTrapIdentification ); +void vSystemBusAndPeripheralsTrap( int iTrapIdentification ); +void vAssertionTrap( int iTrapIdentification ); +void vNonMaskableInterruptTrap( int iTrapIdentification ); +/*---------------------------------------------------------------------------*/ + +void vTrapInstallHandlers( void ) +{ + if ( 0 == _install_trap_handler ( portMMU_TRAP, vMMUTrap ) ) + { + _debug(); + } + if ( 0 == _install_trap_handler ( portIPT_TRAP, vInternalProtectionTrap ) ) + { + _debug(); + } + if ( 0 == _install_trap_handler ( portIE_TRAP, vInstructionErrorTrap ) ) + { + _debug(); + } + if ( 0 == _install_trap_handler ( portCM_TRAP, vContextManagementTrap ) ) + { + _debug(); + } + if ( 0 == _install_trap_handler ( portSBP_TRAP, vSystemBusAndPeripheralsTrap ) ) + { + _debug(); + } + if ( 0 == _install_trap_handler ( portASSERT_TRAP, vAssertionTrap ) ) + { + _debug(); + } +/* Trap Handler 6 (Syscall) is installed in port.c as it is fundamental to + * the OS operation. These trap handlers is are place holders. + * if ( 0 != _install_trap_handler ( portMMU_TRAP, vMMUTrap ) ) + { + _debug(); + } +*/ + if ( 0 == _install_trap_handler ( portNMI_TRAP, vNonMaskableInterruptTrap ) ) + { + _debug(); + } +} +/*-----------------------------------------------------------*/ + +void vMMUTrap( int iTrapIdentification ) +{ + switch ( iTrapIdentification ) + { + case portTIN_MMU_VIRTUAL_ADDRESS_FILL: + case portTIN_MMU_VIRTUAL_ADDRESS_PROTECTION: + default: + _debug(); + break; + } +} +/*---------------------------------------------------------------------------*/ + +void vInternalProtectionTrap( int iTrapIdentification ) +{ + switch ( iTrapIdentification ) + { + case portTIN_IPT_PRIVILIGED_INSTRUCTION: + /* Instruction is not allowed at current execution level, eg DISABLE at User-0. */ + case portTIN_IPT_MEMORY_PROTECTION_READ: + /* Load word using invalid address. */ + case portTIN_IPT_MEMORY_PROTECTION_WRITE: + /* Store Word using invalid address. */ + case portTIN_IPT_MEMORY_PROTECTION_EXECUTION: + /* PC jumped to an address outside of the valid range. */ + case portTIN_IPT_MEMORY_PROTECTION_PERIPHERAL_ACCESS: + /* Access to a peripheral denied at current execution level. */ + case portTIN_IPT_MEMORY_PROTECTION_NULL_ADDRESS: + /* NULL Pointer. */ + case portTIN_IPT_MEMORY_PROTECTION_GLOBAL_REGISTER_WRITE_PROTECTION: + /* Tried to modify a global address pointer register. */ + default: + pxCurrentTCB[ 0 ] = _mfcr( $PCXI ); + _debug(); + break; + } +} +/*---------------------------------------------------------------------------*/ + +void vInstructionErrorTrap( int iTrapIdentification ) +{ + switch ( iTrapIdentification ) + { + case portTIN_IE_ILLEGAL_OPCODE: + case portTIN_IE_UNIMPLEMENTED_OPCODE: + case portTIN_IE_INVALID_OPERAND: + case portTIN_IE_DATA_ADDRESS_ALIGNMENT: + case portTIN_IE_INVALID_LOCAL_MEMORY_ADDRESS: + default: + _debug(); + break; + } +} +/*---------------------------------------------------------------------------*/ + +void vContextManagementTrap( int iTrapIdentification ) +{ + switch ( iTrapIdentification ) + { + case portTIN_CM_FREE_CONTEXT_LIST_DEPLETION: + case portTIN_CM_CALL_DEPTH_OVERFLOW: + case portTIN_CM_CALL_DEPTH_UNDEFLOW: + case portTIN_CM_FREE_CONTEXT_LIST_UNDERFLOW: + case portTIN_CM_CALL_STACK_UNDERFLOW: + case portTIN_CM_CONTEXT_TYPE: + case portTIN_CM_NESTING_ERROR: + default: + _debug(); + break; + } +} +/*---------------------------------------------------------------------------*/ + +void vSystemBusAndPeripheralsTrap( int iTrapIdentification ) +{ + switch ( iTrapIdentification ) + { + case portTIN_SBP_PROGRAM_FETCH_SYNCHRONOUS_ERROR: + case portTIN_SBP_DATA_ACCESS_SYNCHRONOUS_ERROR: + case portTIN_SBP_DATA_ACCESS_ASYNCHRONOUS_ERROR: + case portTIN_SBP_COPROCESSOR_TRAP_ASYNCHRONOUS_ERROR: + case portTIN_SBP_PROGRAM_MEMORY_INTEGRITY_ERROR: + case portTIN_SBP_DATA_MEMORY_INTEGRITY_ERROR: + default: + _debug(); + break; + } +} +/*---------------------------------------------------------------------------*/ + +void vAssertionTrap( int iTrapIdentification ) +{ + switch ( iTrapIdentification ) + { + case portTIN_ASSERT_ARITHMETIC_OVERFLOW: + case portTIN_ASSERT_STICKY_ARITHMETIC_OVERFLOW: + default: + _debug(); + break; + } +} +/*---------------------------------------------------------------------------*/ + +void vNonMaskableInterruptTrap( int iTrapIdentification ) +{ + switch ( iTrapIdentification ) + { + case portTIN_NMI_NON_MASKABLE_INTERRUPT: + default: + _debug(); + break; + } +} +/*---------------------------------------------------------------------------*/