From: richardbarry Date: Tue, 29 Nov 2011 19:02:58 +0000 (+0000) Subject: Update core files to remove legacy trace and make necessary modifications to facilita... X-Git-Tag: V7.1.0~17 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=3cafe2ac446d1e93046a971d89d7b51408314e8b;p=freertos Update core files to remove legacy trace and make necessary modifications to facilitate use with other trace tools. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1643 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/Source/include/FreeRTOS.h b/Source/include/FreeRTOS.h index 4f24ac4ed..155e78075 100644 --- a/Source/include/FreeRTOS.h +++ b/Source/include/FreeRTOS.h @@ -272,6 +272,23 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); #define traceTASK_SWITCHED_OUT() #endif +#ifndef traceTASK_PRIORITY_INHERIT + /* Called when a task attempts to take a mutex that is already held by a + lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + that holds the mutex. uxInheritedPriority is the priority the mutex holder + will inherit (the priority of the task that is attempting to obtain the + muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + /* Called when a task releases a mutex, the holding of which had resulted in + the task inheriting the priority of a higher priority task. + pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + #ifndef traceBLOCKING_ON_QUEUE_RECEIVE /* Task is about to block because it cannot read from a queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore @@ -299,7 +316,7 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); #endif #ifndef traceQUEUE_CREATE_FAILED - #define traceQUEUE_CREATE_FAILED() + #define traceQUEUE_CREATE_FAILED( ucQueueType ) #endif #ifndef traceCREATE_MUTEX diff --git a/Source/include/queue.h b/Source/include/queue.h index 4bc92a6d4..a1ef6de01 100644 --- a/Source/include/queue.h +++ b/Source/include/queue.h @@ -78,6 +78,12 @@ typedef void * xQueueHandle; #define queueSEND_TO_BACK ( 0 ) #define queueSEND_TO_FRONT ( 1 ) +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( 0U ) +#define queueQUEUE_TYPE_MUTEX ( 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U ) /** * queue. h @@ -135,7 +141,7 @@ typedef void * xQueueHandle; * \defgroup xQueueCreate xQueueCreate * \ingroup QueueManagement */ -xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ); +#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE ) /** * queue. h @@ -1218,7 +1224,7 @@ signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, port * For internal use only. Use xSemaphoreCreateMutex() or * xSemaphoreCreateCounting() instead of calling these functions directly. */ -xQueueHandle xQueueCreateMutex( void ); +xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ); xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ); /* @@ -1252,7 +1258,15 @@ portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ); void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ); #endif -/* Not a public API function, hence the 'Restricted' in the name. */ +/* + * Generic version of the queue creation function, which is in turn called by + * any queue, semaphore or mutex creation function or macro. + */ +xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ); + +/* + * Not a public API function, hence the 'Restricted' in the name. + */ void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ); diff --git a/Source/include/semphr.h b/Source/include/semphr.h index b63bb2b61..56a2a217b 100644 --- a/Source/include/semphr.h +++ b/Source/include/semphr.h @@ -105,13 +105,14 @@ typedef xQueueHandle xSemaphoreHandle; * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary * \ingroup Semaphores */ -#define vSemaphoreCreateBinary( xSemaphore ) { \ - ( xSemaphore ) = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \ - if( ( xSemaphore ) != NULL ) \ - { \ - xSemaphoreGive( ( xSemaphore ) ); \ - } \ - } +#define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } /** * semphr. h @@ -585,7 +586,7 @@ typedef xQueueHandle xSemaphoreHandle; * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex * \ingroup Semaphores */ -#define xSemaphoreCreateMutex() xQueueCreateMutex() +#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) /** @@ -640,7 +641,7 @@ typedef xQueueHandle xSemaphoreHandle; * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex * \ingroup Semaphores */ -#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex() +#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) /** * semphr. h diff --git a/Source/include/task.h b/Source/include/task.h index ef38afb3e..79aa7a55c 100644 --- a/Source/include/task.h +++ b/Source/include/task.h @@ -1301,6 +1301,18 @@ void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUN */ signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION; +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask ); + +/* + * Set the uxTCBNumber of the task referenced by the xTask parameter to + * ucHandle. + */ +void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle ); + + #ifdef __cplusplus } #endif diff --git a/Source/queue.c b/Source/queue.c index 39e054eb9..ec6bc59fb 100644 --- a/Source/queue.c +++ b/Source/queue.c @@ -94,6 +94,13 @@ zero. */ #define queueDONT_BLOCK ( ( portTickType ) 0U ) #define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U ) +/* These definitions *must* match those in queue.h. */ +#define queueQUEUE_TYPE_BASE ( 0U ) +#define queueQUEUE_TYPE_MUTEX ( 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U ) + /* * Definition of the queue used by the scheduler. * Items are queued by copy, not reference. @@ -115,6 +122,11 @@ typedef struct QueueDefinition signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if ( configUSE_TRACE_FACILITY == 1 ) + unsigned char ucQueueNumber; + unsigned char ucQueueType; + #endif } xQUEUE; /*-----------------------------------------------------------*/ @@ -131,14 +143,14 @@ typedef xQUEUE * xQueueHandle; * include the API header file (as it defines xQueueHandle differently). These * functions are documented in the API header file. */ -xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) PRIVILEGED_FUNCTION; +xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION; signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION; signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION; -xQueueHandle xQueueCreateMutex( void ) PRIVILEGED_FUNCTION; +xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) PRIVILEGED_FUNCTION; xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION; portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION; portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION; @@ -148,6 +160,8 @@ signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRI signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; +unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; +unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; /* * Co-routine queue functions differ from task queue functions. Co-routines are @@ -246,12 +260,16 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) * PUBLIC QUEUE MANAGEMENT API documented in queue.h *----------------------------------------------------------*/ -xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) +xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) { xQUEUE *pxNewQueue; size_t xQueueSizeInBytes; xQueueHandle xReturn = NULL; + /* Remove compiler warnings about unused parameters should + configUSE_TRACE_FACILITY not be set to 1. */ + ( void ) ucQueueType; + /* Allocate the new queue structure. */ if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) { @@ -275,6 +293,11 @@ xQueueHandle xReturn = NULL; pxNewQueue->uxItemSize = uxItemSize; pxNewQueue->xRxLock = queueUNLOCKED; pxNewQueue->xTxLock = queueUNLOCKED; + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* configUSE_TRACE_FACILITY */ /* Likewise ensure the event queues start with the correct state. */ vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); @@ -285,7 +308,7 @@ xQueueHandle xReturn = NULL; } else { - traceQUEUE_CREATE_FAILED(); + traceQUEUE_CREATE_FAILED( ucQueueType ); vPortFree( pxNewQueue ); } } @@ -299,10 +322,14 @@ xQueueHandle xReturn = NULL; #if ( configUSE_MUTEXES == 1 ) - xQueueHandle xQueueCreateMutex( void ) + xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) { xQUEUE *pxNewQueue; + /* Prevent compiler warnings about unused parameters if + configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + /* Allocate the new queue structure. */ pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); if( pxNewQueue != NULL ) @@ -324,15 +351,21 @@ xQueueHandle xReturn = NULL; pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U; pxNewQueue->xRxLock = queueUNLOCKED; pxNewQueue->xTxLock = queueUNLOCKED; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* Ensure the event queues start with the correct state. */ vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + traceCREATE_MUTEX( pxNewQueue ); + /* Start with the semaphore in the expected state. */ xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK ); - - traceCREATE_MUTEX( pxNewQueue ); } else { @@ -441,7 +474,7 @@ xQueueHandle xReturn = NULL; { xQueueHandle pxHandle; - pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH ); + pxHandle = xQueueGenericCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); if( pxHandle != NULL ) { @@ -1085,6 +1118,26 @@ void vQueueDelete( xQueueHandle pxQueue ) } /*-----------------------------------------------------------*/ +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ) + { + return pxQueue->ucQueueNumber; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) + { + return pxQueue->ucQueueType; + } + +#endif +/*-----------------------------------------------------------*/ + static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) { if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 ) diff --git a/Source/tasks.c b/Source/tasks.c index cf19d34af..7950bf49f 100644 --- a/Source/tasks.c +++ b/Source/tasks.c @@ -194,58 +194,6 @@ PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) #define tskDELETED_CHAR ( ( signed char ) 'D' ) #define tskSUSPENDED_CHAR ( ( signed char ) 'S' ) -/* - * Macros and private variables used by the trace facility. - */ -#if ( configUSE_TRACE_FACILITY == 1 ) - - #define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) ) - PRIVILEGED_DATA static volatile signed char * volatile pcTraceBuffer; - PRIVILEGED_DATA static signed char *pcTraceBufferStart; - PRIVILEGED_DATA static signed char *pcTraceBufferEnd; - PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE; - static unsigned portBASE_TYPE uxPreviousTask = 255U; - PRIVILEGED_DATA static char pcStatusString[ 50 ]; - -#endif - -/*-----------------------------------------------------------*/ - -/* - * Macro that writes a trace of scheduler activity to a buffer. This trace - * shows which task is running when and is very useful as a debugging tool. - * As this macro is called each context switch it is a good idea to undefine - * it if not using the facility. - */ -#if ( configUSE_TRACE_FACILITY == 1 ) - - #define vWriteTraceToBuffer() \ - { \ - if( xTracing != pdFALSE ) \ - { \ - if( uxPreviousTask != pxCurrentTCB->uxTCBNumber ) \ - { \ - if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \ - { \ - uxPreviousTask = pxCurrentTCB->uxTCBNumber; \ - *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \ - pcTraceBuffer += sizeof( unsigned long ); \ - *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \ - pcTraceBuffer += sizeof( unsigned long ); \ - } \ - else \ - { \ - xTracing = pdFALSE; \ - } \ - } \ - } \ - } - -#else - - #define vWriteTraceToBuffer() - -#endif /*-----------------------------------------------------------*/ /* @@ -818,7 +766,7 @@ tskTCB * pxNewTCB; priority of the calling function. */ pxTCB = prvGetTCBFromHandle( pxTask ); - traceTASK_PRIORITY_SET( pxTask, uxNewPriority ); + traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); #if ( configUSE_MUTEXES == 1 ) { @@ -1450,44 +1398,6 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) #endif /*----------------------------------------------------------*/ -#if ( configUSE_TRACE_FACILITY == 1 ) - - void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize ) - { - configASSERT( pcBuffer ); - configASSERT( ulBufferSize ); - - taskENTER_CRITICAL(); - { - pcTraceBuffer = ( signed char * )pcBuffer; - pcTraceBufferStart = pcBuffer; - pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE ); - xTracing = pdTRUE; - } - taskEXIT_CRITICAL(); - } - -#endif -/*----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - unsigned long ulTaskEndTrace( void ) - { - unsigned long ulBufferLength; - - taskENTER_CRITICAL(); - xTracing = pdFALSE; - taskEXIT_CRITICAL(); - - ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart ); - - return ulBufferLength; - } - -#endif -/*----------------------------------------------------------*/ - #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) xTaskHandle xTaskGetIdleTaskHandle( void ) @@ -1714,7 +1624,6 @@ void vTaskSwitchContext( void ) listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); traceTASK_SWITCHED_IN(); - vWriteTraceToBuffer(); } } /*-----------------------------------------------------------*/ @@ -1910,6 +1819,42 @@ void vTaskMissedYield( void ) { xMissedYield = pdTRUE; } +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask ) + { + unsigned portBASE_TYPE uxReturn; + tskTCB *pxTCB; + + if( xTask != NULL ) + { + pxTCB = ( tskTCB * ) xTask; + uxReturn = pxTCB->uxTCBNumber; + } + else + { + uxReturn = 0U; + } + + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle ) + { + tskTCB *pxTCB; + + if( xTask != NULL ) + { + pxTCB = ( tskTCB * ) xTask; + pxTCB->uxTCBNumber = uxHandle; + } + } +#endif + /* * ----------------------------------------------------------- @@ -2204,6 +2149,7 @@ tskTCB *pxNewTCB; { volatile tskTCB *pxNextTCB, *pxFirstTCB; unsigned short usStackRemaining; + PRIVILEGED_DATA static char pcStatusString[ 50 ]; /* Write the details of all the TCB's in pxList into the buffer. */ listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); @@ -2441,6 +2387,8 @@ tskTCB *pxNewTCB; /* Just inherit the priority. */ pxTCB->uxPriority = pxCurrentTCB->uxPriority; } + + traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority ); } } @@ -2461,8 +2409,9 @@ tskTCB *pxNewTCB; Remove ourselves from the ready list we currently appear in. */ vListRemove( &( pxTCB->xGenericListItem ) ); - /* Disinherit the priority before adding ourselves into the new + /* Disinherit the priority before adding the task into the new ready list. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); pxTCB->uxPriority = pxTCB->uxBasePriority; listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority ); prvAddTaskToReadyQueue( pxTCB );