First commit with TriCore port and demo - still a work in progress.

This commit is contained in:
Richard Barry 2011-10-17 13:17:58 +00:00
parent 75dc89826f
commit 45fe448d73
4 changed files with 1480 additions and 0 deletions

View File

@ -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 */

View File

@ -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 <stdlib.h>
#include <string.h>
#include <tc1782.h>
#include <machine/intrinsics.h>
#include <machine/cint.h>
#include <machine/wdtcon.h>
/* 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;
}
}
/*-----------------------------------------------------------*/

View File

@ -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 <tc1782.h>
#include <machine/intrinsics.h>
/*-----------------------------------------------------------
* 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 */

View File

@ -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 <tc1782.h>
#include <machine/intrinsics.h>
#include <machine/cint.h>
/*---------------------------------------------------------------------------*/
/*
* 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;
}
}
/*---------------------------------------------------------------------------*/