From b0d1cb7c5446ad893ed8602b3a82f56978ae830d Mon Sep 17 00:00:00 2001 From: richardbarry Date: Mon, 24 Oct 2011 12:30:35 +0000 Subject: [PATCH] Minor changes to the TriCore port made during test/validation. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1623 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/include/FreeRTOS.h | 3 + Source/portable/GCC/TriCore_1782/port.c | 78 +++++++++++--------- Source/portable/GCC/TriCore_1782/portmacro.h | 7 ++ Source/tasks.c | 4 + 4 files changed, 57 insertions(+), 35 deletions(-) diff --git a/Source/include/FreeRTOS.h b/Source/include/FreeRTOS.h index b2446430a..baa77afbc 100644 --- a/Source/include/FreeRTOS.h +++ b/Source/include/FreeRTOS.h @@ -226,6 +226,9 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue #endif +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif #ifndef configQUEUE_REGISTRY_SIZE #define configQUEUE_REGISTRY_SIZE 0U diff --git a/Source/portable/GCC/TriCore_1782/port.c b/Source/portable/GCC/TriCore_1782/port.c index eadcc0170..4f4dc4d27 100644 --- a/Source/portable/GCC/TriCore_1782/port.c +++ b/Source/portable/GCC/TriCore_1782/port.c @@ -75,6 +75,7 @@ #define portINITIAL_SYSCON ( (unsigned portBASE_TYPE) 0x00000000 ) /* MPU Disable. */ +/* This macro should be used when the MPU is being used. */ #define portSELECT_PROGRAM_STATUS_WORD( xRunPrivileged ) ( ( xRunPrivileged ) ? portINITIAL_PRIVILEGED_PROGRAM_STATUS_WORD : portINITIAL_UNPRIVILEGED_PROGRAM_STATUS_WORD ) /* CSA manipulation macros. */ @@ -173,7 +174,7 @@ unsigned portBASE_TYPE *pxLowerCSA = NULL; /* Upper Context. */ pxUpperCSA[ 2 ] = (unsigned portBASE_TYPE)pxTopOfStack; /* A10; Stack Return aka Stack Pointer */ - pxUpperCSA[ 1 ] = portSELECT_PROGRAM_STATUS_WORD( pdTRUE ); /* PSW */ + pxUpperCSA[ 1 ] = portSYSTEM_PROGRAM_STATUS_WORD; /* PSW */ /* Clear the CSA. */ memset( pxLowerCSA, 0, 16 * sizeof( unsigned portBASE_TYPE ) ); @@ -318,50 +319,57 @@ void vPortSystemTickHandler( int iArg ) void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB ) { unsigned portBASE_TYPE pxHeadCSA, pxTailCSA, pxFreeCSA; +unsigned portBASE_TYPE *pulNextCSA; - /* 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. */ + /* A pointer to the first CSA in the list of CSAs consumed by the task is + stored in the first element of the tasks TCB structure (where the stack + pointer would be on a traditional stack based architecture). */ pxHeadCSA = ( *pxTCB ) & portCSA_FCX_MASK; - /* If there is something to reclaim. */ - if ( 0UL != ( pxHeadCSA & portCSA_FCX_MASK ) ) + /* Mask off everything in the CSA link field other than the address. If + the address is NULL, then the CSA is not linking anywhere and there is + nothing to do. */ + pxTailCSA = pxHeadCSA; + + /* Convert the link value to contain just a raw address and store this + in a local variable. */ + pulNextCSA = portCSA_TO_ADDRESS( pxTailCSA ); + + /* Iterate over the CSAs that were consumed as part of the task. The + first field in the CSA is the pointer to then next CSA. Mask off + everything in the pointer to the next CSA, other than the link address. + If this is NULL, then the CSA currently being pointed to is the last in + the chain. */ + while( 0UL != ( pulNextCSA[ 0 ] & 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; + /* Clear all bits of the pointer to the next in the chain, other + than the address bits themselves. */ + pulNextCSA[ 0 ] = pulNextCSA[ 0 ] & portCSA_FCX_MASK; - /* Iterate to the next CSA. */ - pxTailCSA = portCSA_TO_ADDRESS( pxTailCSA )[ 0 ]; - } + /* Move the pointer to point to the next CSA in the list. */ + pxTailCSA = pulNextCSA[ 0 ]; - /* pxHeadCSA points to the first in the chain - * pxNextCSA points to the Head or the last in the chain. - */ + /* Update the local pointer to the CSA. */ + pulNextCSA = portCSA_TO_ADDRESS( pxTailCSA ); + } - portENTER_CRITICAL(); - { - /* Look up the current free CSA. */ - _dsync(); - pxFreeCSA = _mfcr( $FCX ); + taskENTER_CRITICAL(); + { + /* Look up the current free CSA head. */ + _dsync(); + pxFreeCSA = _mfcr( $FCX ); - /* Join the current Free onto the Tail of what is being reclaimed. */ - portCSA_TO_ADDRESS( pxTailCSA )[ 0 ] = pxFreeCSA; + /* 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(); + /* Move the head of the reclaimed into the Free. */ + _dsync(); + _mtcr( $FCX, pxHeadCSA ); + + /* ISync to commit the change to the FCX. */ + _isync(); } + taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ diff --git a/Source/portable/GCC/TriCore_1782/portmacro.h b/Source/portable/GCC/TriCore_1782/portmacro.h index 17f20e698..65cb1926c 100644 --- a/Source/portable/GCC/TriCore_1782/portmacro.h +++ b/Source/portable/GCC/TriCore_1782/portmacro.h @@ -187,6 +187,13 @@ unsigned portBASE_TYPE xUpperCSA = 0UL; \ #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /*---------------------------------------------------------------------------*/ +/* + * Port specific clean up macro required to free the CSAs that were consumed by + * a task that has since been deleted. + */ +void vPortReclaimCSA( unsigned portBASE_TYPE *pxTCB ); +#define portCLEAN_UP_TCB( pxTCB ) vPortReclaimCSA( ( unsigned portBASE_TYPE *) ( pxTCB ) ) + #ifdef __cplusplus } #endif diff --git a/Source/tasks.c b/Source/tasks.c index a7d4f2370..3a4b21d75 100644 --- a/Source/tasks.c +++ b/Source/tasks.c @@ -2347,6 +2347,10 @@ tskTCB *pxNewTCB; static void prvDeleteTCB( tskTCB *pxTCB ) { + /* This call is required specifically for the TriCore port. It must be + above the vPortFree() calls. */ + portCLEAN_UP_TCB( pxTCB ); + /* Free up the memory allocated by the scheduler for the task. It is up to the task to free any memory allocated at the application level. */ vPortFreeAligned( pxTCB->pxStack ); -- 2.39.5