diff --git a/FreeRTOS/Source/event_groups.c b/FreeRTOS/Source/event_groups.c index 859a54439..9747e0417 100644 --- a/FreeRTOS/Source/event_groups.c +++ b/FreeRTOS/Source/event_groups.c @@ -87,8 +87,8 @@ privileged Vs unprivileged linkage and placement. */ #error configUSE_TIMERS must be set to 1 to make the xEventGroupSetBitFromISR() function available. #endif -#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCallFromISR == 0 ) - #error INCLUDE_xTimerPendFunctionCallFromISR must also be set to one to make the xEventGroupSetBitFromISR() function available. +#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 0 ) + #error INCLUDE_xTimerPendFunctionCall must also be set to one to make the xEventGroupSetBitFromISR() function available. #endif /* The following bit fields convey control information in a task's event list @@ -110,6 +110,11 @@ typedef struct EVENT_GROUP_DEFINITION { EventBits_t uxEventBits; List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + } EventGroup_t; /*-----------------------------------------------------------*/ @@ -151,6 +156,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u EventBits_t uxOriginalBitValue, uxReturn; EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; BaseType_t xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( uxBitsToWaitFor != 0 ); @@ -162,8 +168,6 @@ BaseType_t xAlreadyYielded; vTaskSuspendAll(); { - traceEVENT_GROUP_SYNC_START( xEventGroup, uxBitsToSet ); - uxOriginalBitValue = pxEventBits->uxEventBits; ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); @@ -183,6 +187,8 @@ BaseType_t xAlreadyYielded; { if( xTicksToWait != ( TickType_t ) 0 ) { + traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); + /* Store the bits that the calling task is waiting for in the task's event list item so the kernel knows when a match is found. Then enter the blocked state. */ @@ -242,6 +248,8 @@ BaseType_t xAlreadyYielded; } } taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdTRUE; } else { @@ -251,7 +259,7 @@ BaseType_t xAlreadyYielded; } } - traceEVENT_GROUP_SYNC_END( xEventGroup, uxReturn ); + traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); return uxReturn; } /*-----------------------------------------------------------*/ @@ -261,6 +269,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; EventBits_t uxReturn, uxControlBits = 0; BaseType_t xWaitConditionMet, xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; /* Check the user is not attempting to wait on the bits used by the kernel itself, and that at least one bit is being requested. */ @@ -276,8 +285,6 @@ BaseType_t xWaitConditionMet, xAlreadyYielded; { const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; - traceEVENT_GROUP_WAIT_BITS_START( xEventGroup, uxBitsToWaitFor ); - /* Check to see if the wait condition is already met or not. */ xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); @@ -337,6 +344,8 @@ BaseType_t xWaitConditionMet, xAlreadyYielded; some compilers mistakenly generate a warning about the variable being returned without being set if it is not done. */ uxReturn = 0; + + traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); } } xAlreadyYielded = xTaskResumeAll(); @@ -384,6 +393,8 @@ BaseType_t xWaitConditionMet, xAlreadyYielded; } } taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdFALSE; } else { @@ -392,8 +403,7 @@ BaseType_t xWaitConditionMet, xAlreadyYielded; uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; } } - - traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxReturn ); + traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); return uxReturn; } /*-----------------------------------------------------------*/ @@ -608,5 +618,24 @@ BaseType_t xWaitConditionMet = pdFALSE; return xWaitConditionMet; } +/*-----------------------------------------------------------*/ +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) + { + UBaseType_t xReturn; + EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; + + if( xEventGroup == NULL ) + { + xReturn = 0; + } + else + { + xReturn = pxEventBits->uxEventGroupNumber; + } + + return xReturn; + } +#endif diff --git a/FreeRTOS/Source/include/FreeRTOS.h b/FreeRTOS/Source/include/FreeRTOS.h index 43d7f7191..2f1c28534 100644 --- a/FreeRTOS/Source/include/FreeRTOS.h +++ b/FreeRTOS/Source/include/FreeRTOS.h @@ -249,8 +249,8 @@ is included as it is used by the port layer. */ #define INCLUDE_xEventGroupSetBitFromISR 0 #endif -#ifndef INCLUDE_xTimerPendFunctionCallFromISR - #define INCLUDE_xTimerPendFunctionCallFromISR 0 +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 #endif #ifndef configASSERT @@ -567,20 +567,20 @@ is included as it is used by the port layer. */ #define traceEVENT_GROUP_CREATE_FAILED() #endif -#ifndef traceEVENT_GROUP_SYNC_START - #define traceEVENT_GROUP_SYNC_START( xEventGroup, uxBitsToSet ) +#ifndef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) #endif #ifndef traceEVENT_GROUP_SYNC_END - #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxReturn ) + #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred #endif -#ifndef traceEVENT_GROUP_WAIT_BITS_START - #define traceEVENT_GROUP_WAIT_BITS_START( xEventGroup, uxBitsToWaitFor ) +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) #endif #ifndef traceEVENT_GROUP_WAIT_BITS_END - #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxReturn ) + #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred #endif #ifndef traceEVENT_GROUP_CLEAR_BITS @@ -595,10 +595,26 @@ is included as it is used by the port layer. */ #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) #endif +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + #ifndef traceEVENT_GROUP_DELETE #define traceEVENT_GROUP_DELETE( xEventGroup ) #endif +#ifndef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) +#endif + #ifndef configGENERATE_RUN_TIME_STATS #define configGENERATE_RUN_TIME_STATS 0 #endif diff --git a/FreeRTOS/Source/include/event_groups.h b/FreeRTOS/Source/include/event_groups.h index 4407fff65..32cafea7d 100644 --- a/FreeRTOS/Source/include/event_groups.h +++ b/FreeRTOS/Source/include/event_groups.h @@ -663,6 +663,9 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup ); /* For internal use only. */ void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ); +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ); +#endif #ifdef __cplusplus } diff --git a/FreeRTOS/Source/include/queue.h b/FreeRTOS/Source/include/queue.h index d160a0fcd..8a83ef258 100644 --- a/FreeRTOS/Source/include/queue.h +++ b/FreeRTOS/Source/include/queue.h @@ -1370,7 +1370,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pv void vAFunction( void *pvParameters ) { char cValueToPost; - const TickType_t xBlockTime = ( TickType_t )0xff; + const TickType_t xTicksToWait = ( TickType_t )0xff; // Create a queue capable of containing 10 characters. xQueue = xQueueCreate( 10, sizeof( char ) ); @@ -1382,17 +1382,17 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pv // ... // Post some characters that will be used within an ISR. If the queue - // is full then this task will block for xBlockTime ticks. + // is full then this task will block for xTicksToWait ticks. cValueToPost = 'a'; - xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); + xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); cValueToPost = 'b'; - xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); + xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); // ... keep posting characters ... this task may block when the queue // becomes full. cValueToPost = 'c'; - xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); + xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); } // ISR that outputs all the characters received on the queue. @@ -1480,7 +1480,7 @@ void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; * For internal use only. Use xSemaphoreTakeMutexRecursive() or * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. */ -BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) PRIVILEGED_FUNCTION; +BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION; /* @@ -1653,7 +1653,7 @@ BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueS * * @param xQueueSet The queue set on which the task will (potentially) block. * - * @param xBlockTimeTicks The maximum time, in ticks, that the calling task will + * @param xTicksToWait The maximum time, in ticks, that the calling task will * remain in the Blocked state (with other tasks executing) to wait for a member * of the queue set to be ready for a successful queue read or semaphore take * operation. @@ -1664,7 +1664,7 @@ BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueS * in the queue set that is available, or NULL if no such queue or semaphore * exists before before the specified block time expires. */ -QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xBlockTimeTicks ) PRIVILEGED_FUNCTION; +QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; /* * A version of xQueueSelectFromSet() that can be used from an ISR. diff --git a/FreeRTOS/Source/include/timers.h b/FreeRTOS/Source/include/timers.h index 2b9698d36..b25144eb0 100644 --- a/FreeRTOS/Source/include/timers.h +++ b/FreeRTOS/Source/include/timers.h @@ -89,18 +89,19 @@ be used solely through the macros that make up the public software timer API, as defined below. The commands that are sent from interrupts must use the highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task or interrupt version of the queue send function should be used. */ -#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) -#define tmrCOMMAND_START ( ( BaseType_t ) 0 ) -#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 1 ) -#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) -#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) -#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) -#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) -#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) -#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 7 ) -#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 8 ) -#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 9 ) +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) /** @@ -111,13 +112,13 @@ or interrupt version of the queue send function should be used. */ */ typedef void * TimerHandle_t; -/* - * Defines the prototype to which timer callback functions must conform. +/* + * Defines the prototype to which timer callback functions must conform. */ typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); -/* - * Defines the prototype to which functions used with the +/* + * Defines the prototype to which functions used with the * xTimerPendFunctionCallFromISR() function must conform. */ typedef void (*PendedFunction_t)( void *, uint32_t ); @@ -324,7 +325,7 @@ BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); /** - * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xBlockTime ); + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task @@ -353,14 +354,14 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * * @param xTimer The handle of the timer being started/restarted. * - * @param xBlockTime Specifies the time, in ticks, that the calling task should + * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the start command to be successfully * sent to the timer command queue, should the queue already be full when - * xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called * before the scheduler is started. * * @return pdFAIL will be returned if the start command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will * be returned if the command was successfully sent to the timer command queue. * When the command is actually processed will depend on the priority of the * timer service/daemon task relative to other tasks in the system, although the @@ -373,10 +374,10 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * See the xTimerCreate() API function example usage scenario. * */ -#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) +#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) /** - * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xBlockTime ); + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task @@ -396,14 +397,14 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * * @param xTimer The handle of the timer being stopped. * - * @param xBlockTime Specifies the time, in ticks, that the calling task should + * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the stop command to be successfully * sent to the timer command queue, should the queue already be full when - * xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called * before the scheduler is started. * * @return pdFAIL will be returned if the stop command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will * be returned if the command was successfully sent to the timer command queue. * When the command is actually processed will depend on the priority of the * timer service/daemon task relative to other tasks in the system. The timer @@ -415,12 +416,12 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * See the xTimerCreate() API function example usage scenario. * */ -#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) ) +#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) /** * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, * TickType_t xNewPeriod, - * TickType_t xBlockTime ); + * TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task @@ -448,14 +449,14 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than * or equal to 1000. * - * @param xBlockTime Specifies the time, in ticks, that the calling task should + * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the change period command to be * successfully sent to the timer command queue, should the queue already be - * full when xTimerChangePeriod() was called. xBlockTime is ignored if + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if * xTimerChangePeriod() is called before the scheduler is started. * * @return pdFAIL will be returned if the change period command could not be - * sent to the timer command queue even after xBlockTime ticks had passed. + * sent to the timer command queue even after xTicksToWait ticks had passed. * pdPASS will be returned if the command was successfully sent to the timer * command queue. When the command is actually processed will depend on the * priority of the timer service/daemon task relative to other tasks in the @@ -495,10 +496,10 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * } * @endverbatim */ - #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) ) + #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) /** - * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xBlockTime ); + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task @@ -515,14 +516,14 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * * @param xTimer The handle of the timer being deleted. * - * @param xBlockTime Specifies the time, in ticks, that the calling task should + * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the delete command to be * successfully sent to the timer command queue, should the queue already be - * full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete() + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() * is called before the scheduler is started. * * @return pdFAIL will be returned if the delete command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will * be returned if the command was successfully sent to the timer command queue. * When the command is actually processed will depend on the priority of the * timer service/daemon task relative to other tasks in the system. The timer @@ -533,10 +534,10 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * * See the xTimerChangePeriod() API function example usage scenario. */ -#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) ) +#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) /** - * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xBlockTime ); + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); * * Timer functionality is provided by a timer service/daemon task. Many of the * public FreeRTOS timer API functions send commands to the timer service task @@ -567,14 +568,14 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * * @param xTimer The handle of the timer being reset/started/restarted. * - * @param xBlockTime Specifies the time, in ticks, that the calling task should + * @param xTicksToWait Specifies the time, in ticks, that the calling task should * be held in the Blocked state to wait for the reset command to be successfully * sent to the timer command queue, should the queue already be full when - * xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called * before the scheduler is started. * * @return pdFAIL will be returned if the reset command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will * be returned if the command was successfully sent to the timer command queue. * When the command is actually processed will depend on the priority of the * timer service/daemon task relative to other tasks in the system, although the @@ -657,7 +658,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * } * @endverbatim */ -#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) +#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) /** * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, @@ -976,13 +977,13 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); * * * Used from application interrupt service routines to defer the execution of a - * function to the RTOS daemon task (the timer service task, hence this function + * function to the RTOS daemon task (the timer service task, hence this function * is implemented in timers.c and is prefixed with 'Timer'). * * Ideally an interrupt service routine (ISR) is kept as short as possible, but * sometimes an ISR either has a lot of processing to do, or needs to perform - * processing that is not deterministic. In these cases - * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function * to the RTOS daemon task. * * A mechanism is provided that allows the interrupt to return directly to the @@ -1058,12 +1059,46 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); */ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ); + /** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ); + /* * Functions beyond this part are not part of the public API and are intended * for use by the kernel only. */ BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; -BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xBlockTime ) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; #ifdef __cplusplus } diff --git a/FreeRTOS/Source/portable/IAR/RL78/port.c b/FreeRTOS/Source/portable/IAR/RL78/port.c index aa352fbc1..24178e9fb 100644 --- a/FreeRTOS/Source/portable/IAR/RL78/port.c +++ b/FreeRTOS/Source/portable/IAR/RL78/port.c @@ -1,5 +1,5 @@ /* - FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. + FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. All rights reserved VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. @@ -120,6 +120,11 @@ static void prvSetupTimerInterrupt( void ); */ extern void vPortStartFirstTask( void ); +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + /*-----------------------------------------------------------*/ /* @@ -132,9 +137,13 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px { uint32_t *pulLocal; + /* With large code and large data sizeof( StackType_t ) == 2, and + sizeof( StackType_t * ) == 4. With small code and small data + sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */ + #if __DATA_MODEL__ == __DATA_MODEL_FAR__ { - /* Parameters are passed in on the stack, and written using a 32bit value + /* Parameters are passed in on the stack, and written using a 32-bit value hence a space is left for the second two bytes. */ pxTopOfStack--; @@ -143,14 +152,15 @@ uint32_t *pulLocal; *pulLocal = ( uint32_t ) pvParameters; pxTopOfStack--; - /* These values are just spacers. The return address of the function - would normally be written here. */ - *pxTopOfStack = ( StackType_t ) 0xcdcd; + /* The return address, leaving space for the first two bytes of the + 32-bit value. See the comments above the prvTaskExitError() prototype + at the top of this file. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0xcdcd; + pulLocal = ( uint32_t * ) pxTopOfStack; + *pulLocal = ( uint32_t ) prvTaskExitError; pxTopOfStack--; - /* The start address / PSW value is also written in as a 32bit value, + /* The start address / PSW value is also written in as a 32-bit value, so leave a space for the second two bytes. */ pxTopOfStack--; @@ -165,9 +175,16 @@ uint32_t *pulLocal; } #else { - /* Task function address is written to the stack first. As it is - written as a 32bit value a space is left on the stack for the second - two bytes. */ + /* The return address, leaving space for the first two bytes of the + 32-bit value. See the comments above the prvTaskExitError() prototype + at the top of this file. */ + pxTopOfStack--; + pulLocal = ( uint32_t * ) pxTopOfStack; + *pulLocal = ( uint32_t ) prvTaskExitError; + pxTopOfStack--; + + /* Task function. Again as it is written as a 32-bit value a space is + left on the stack for the second two bytes. */ pxTopOfStack--; /* Task function start address combined with the PSW. */ @@ -205,6 +222,20 @@ uint32_t *pulLocal; } /*-----------------------------------------------------------*/ +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( usCriticalNesting == ~0U ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + BaseType_t xPortStartScheduler( void ) { /* Setup the hardware to generate the tick. Interrupts are disabled when diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c index bb391020d..3fb1b6ce5 100644 --- a/FreeRTOS/Source/queue.c +++ b/FreeRTOS/Source/queue.c @@ -512,7 +512,7 @@ QueueHandle_t xReturn = NULL; #if ( configUSE_RECURSIVE_MUTEXES == 1 ) - BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) + BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) { BaseType_t xReturn; Queue_t * const pxMutex = ( Queue_t * ) xMutex; @@ -531,7 +531,7 @@ QueueHandle_t xReturn = NULL; } else { - xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE ); + xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE ); /* pdPASS will only be returned if we successfully obtained the mutex, we may have blocked to reach here. */ @@ -2156,6 +2156,8 @@ BaseType_t xReturn; /* Store the information on this queue. */ xQueueRegistry[ ux ].pcQueueName = pcQueueName; xQueueRegistry[ ux ].xHandle = xQueue; + + traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ); break; } else @@ -2251,26 +2253,26 @@ BaseType_t xReturn; { BaseType_t xReturn; - if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + taskENTER_CRITICAL(); { - /* Cannot add a queue/semaphore to more than one queue set. */ - xReturn = pdFAIL; - } - else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) - { - /* Cannot add a queue/semaphore to a queue set if there are already - items in the queue/semaphore. */ - xReturn = pdFAIL; - } - else - { - taskENTER_CRITICAL(); + if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + { + /* Cannot add a queue/semaphore to more than one queue set. */ + xReturn = pdFAIL; + } + else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* Cannot add a queue/semaphore to a queue set if there are already + items in the queue/semaphore. */ + xReturn = pdFAIL; + } + else { ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; + xReturn = pdPASS; } - taskEXIT_CRITICAL(); - xReturn = pdPASS; } + taskEXIT_CRITICAL(); return xReturn; } @@ -2316,11 +2318,11 @@ BaseType_t xReturn; #if ( configUSE_QUEUE_SETS == 1 ) - QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xBlockTimeTicks ) + QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait ) { QueueSetMemberHandle_t xReturn = NULL; - ( void ) xQueueGenericReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */ + ( void ) xQueueGenericReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */ return xReturn; } diff --git a/FreeRTOS/Source/timers.c b/FreeRTOS/Source/timers.c index 26f537d72..8f6747a89 100644 --- a/FreeRTOS/Source/timers.c +++ b/FreeRTOS/Source/timers.c @@ -76,8 +76,8 @@ task.h is included from an application file. */ #include "queue.h" #include "timers.h" -#if ( INCLUDE_xTimerPendFunctionCallFromISR == 1 ) && ( configUSE_TIMERS == 0 ) - #error configUSE_TIMERS must be set to 1 to make the INCLUDE_xTimerPendFunctionCallFromISR() function available. +#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) + #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. #endif /* Lint e961 and e750 are suppressed as a MISRA exception justified because the @@ -140,9 +140,9 @@ typedef struct tmrTimerQueueMessage /* Don't include xCallbackParameters if it is not going to be used as it makes the structure (and therefore the timer queue) larger. */ - #if ( INCLUDE_xTimerPendFunctionCallFromISR == 1 ) + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) CallbackParameters_t xCallbackParameters; - #endif /* INCLUDE_xTimerPendFunctionCallFromISR */ + #endif /* INCLUDE_xTimerPendFunctionCall */ } u; } DaemonTaskMessage_t; @@ -305,7 +305,7 @@ Timer_t *pxNewTimer; } /*-----------------------------------------------------------*/ -BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xBlockTime ) +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) { BaseType_t xReturn = pdFAIL; DaemonTaskMessage_t xMessage; @@ -323,7 +323,7 @@ DaemonTaskMessage_t xMessage; { if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) { - xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime ); + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); } else { @@ -575,9 +575,11 @@ TickType_t xTimeNow; while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ { - #if ( INCLUDE_xTimerPendFunctionCallFromISR == 1 ) + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) { - if( xMessage.xMessageID == tmrCOMMAND_EXECUTE_CALLBACK ) + /* Negative commands are pended function calls rather than timer + commands. */ + if( xMessage.xMessageID < 0 ) { const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); @@ -593,9 +595,11 @@ TickType_t xTimeNow; mtCOVERAGE_TEST_MARKER(); } } - #endif /* INCLUDE_xTimerPendFunctionCallFromISR */ + #endif /* INCLUDE_xTimerPendFunctionCall */ - if( xMessage.xMessageID != tmrCOMMAND_EXECUTE_CALLBACK ) + /* Commands that are positive are timer commands rather than pended + function calls. */ + if( xMessage.xMessageID >= 0 ) { /* The messages uses the xTimerParameters member to work on a software timer. */ @@ -811,11 +815,35 @@ Timer_t * const pxTimer = ( Timer_t * ) xTimer; } /*-----------------------------------------------------------*/ -#if( INCLUDE_xTimerPendFunctionCallFromISR == 1 ) +#if( INCLUDE_xTimerPendFunctionCall == 1 ) BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) { DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + + tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) + { + DaemonTaskMessage_t xMessage; BaseType_t xReturn; /* Complete the message with the function parameters and post it to the @@ -825,12 +853,14 @@ Timer_t * const pxTimer = ( Timer_t * ) xTimer; xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; - xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + return xReturn; } -#endif /* INCLUDE_xTimerPendFunctionCallFromISR */ +#endif /* INCLUDE_xTimerPendFunctionCall */ /*-----------------------------------------------------------*/ /* This entire source file will be skipped if the application is not configured