#error configUSE_TIMERS must be set to 1 to make the xEventGroupSetBitFromISR() function available.\r
#endif\r
\r
-#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCallFromISR == 0 )\r
- #error INCLUDE_xTimerPendFunctionCallFromISR must also be set to one to make the xEventGroupSetBitFromISR() function available.\r
+#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 0 )\r
+ #error INCLUDE_xTimerPendFunctionCall must also be set to one to make the xEventGroupSetBitFromISR() function available.\r
#endif\r
\r
/* The following bit fields convey control information in a task's event list\r
{\r
EventBits_t uxEventBits;\r
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */\r
+\r
+ #if( configUSE_TRACE_FACILITY == 1 )\r
+ UBaseType_t uxEventGroupNumber;\r
+ #endif\r
+\r
} EventGroup_t;\r
\r
/*-----------------------------------------------------------*/\r
EventBits_t uxOriginalBitValue, uxReturn;\r
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
BaseType_t xAlreadyYielded;\r
+BaseType_t xTimeoutOccurred = pdFALSE;\r
\r
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );\r
configASSERT( uxBitsToWaitFor != 0 );\r
\r
vTaskSuspendAll();\r
{\r
- traceEVENT_GROUP_SYNC_START( xEventGroup, uxBitsToSet );\r
-\r
uxOriginalBitValue = pxEventBits->uxEventBits;\r
\r
( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );\r
{\r
if( xTicksToWait != ( TickType_t ) 0 )\r
{\r
+ traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );\r
+\r
/* Store the bits that the calling task is waiting for in the\r
task's event list item so the kernel knows when a match is\r
found. Then enter the blocked state. */\r
}\r
}\r
taskEXIT_CRITICAL();\r
+\r
+ xTimeoutOccurred = pdTRUE;\r
}\r
else\r
{\r
}\r
}\r
\r
- traceEVENT_GROUP_SYNC_END( xEventGroup, uxReturn );\r
+ traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );\r
return uxReturn;\r
}\r
/*-----------------------------------------------------------*/\r
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
EventBits_t uxReturn, uxControlBits = 0;\r
BaseType_t xWaitConditionMet, xAlreadyYielded;\r
+BaseType_t xTimeoutOccurred = pdFALSE;\r
\r
/* Check the user is not attempting to wait on the bits used by the kernel\r
itself, and that at least one bit is being requested. */\r
{\r
const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;\r
\r
- traceEVENT_GROUP_WAIT_BITS_START( xEventGroup, uxBitsToWaitFor );\r
-\r
/* Check to see if the wait condition is already met or not. */\r
xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );\r
\r
some compilers mistakenly generate a warning about the variable\r
being returned without being set if it is not done. */\r
uxReturn = 0;\r
+\r
+ traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );\r
}\r
}\r
xAlreadyYielded = xTaskResumeAll();\r
}\r
}\r
taskEXIT_CRITICAL();\r
+\r
+ xTimeoutOccurred = pdFALSE;\r
}\r
else\r
{\r
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;\r
}\r
}\r
-\r
- traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxReturn );\r
+ traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );\r
return uxReturn;\r
}\r
/*-----------------------------------------------------------*/\r
\r
return xWaitConditionMet;\r
}\r
+/*-----------------------------------------------------------*/\r
\r
+#if (configUSE_TRACE_FACILITY == 1)\r
+ UBaseType_t uxEventGroupGetNumber( void* xEventGroup )\r
+ {\r
+ UBaseType_t xReturn;\r
+ EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
+\r
+ if( xEventGroup == NULL )\r
+ {\r
+ xReturn = 0;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pxEventBits->uxEventGroupNumber;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+#endif\r
\r
#define INCLUDE_xEventGroupSetBitFromISR 0\r
#endif\r
\r
-#ifndef INCLUDE_xTimerPendFunctionCallFromISR\r
- #define INCLUDE_xTimerPendFunctionCallFromISR 0\r
+#ifndef INCLUDE_xTimerPendFunctionCall\r
+ #define INCLUDE_xTimerPendFunctionCall 0\r
#endif\r
\r
#ifndef configASSERT\r
#define traceEVENT_GROUP_CREATE_FAILED()\r
#endif\r
\r
-#ifndef traceEVENT_GROUP_SYNC_START\r
- #define traceEVENT_GROUP_SYNC_START( xEventGroup, uxBitsToSet )\r
+#ifndef traceEVENT_GROUP_SYNC_BLOCK\r
+ #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor )\r
#endif\r
\r
#ifndef traceEVENT_GROUP_SYNC_END\r
- #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxReturn )\r
+ #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred\r
#endif\r
\r
-#ifndef traceEVENT_GROUP_WAIT_BITS_START\r
- #define traceEVENT_GROUP_WAIT_BITS_START( xEventGroup, uxBitsToWaitFor )\r
+#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK\r
+ #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor )\r
#endif\r
\r
#ifndef traceEVENT_GROUP_WAIT_BITS_END\r
- #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxReturn )\r
+ #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred\r
#endif\r
\r
#ifndef traceEVENT_GROUP_CLEAR_BITS\r
#define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet )\r
#endif\r
\r
+#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR\r
+ #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet )\r
+#endif\r
+\r
#ifndef traceEVENT_GROUP_DELETE\r
#define traceEVENT_GROUP_DELETE( xEventGroup )\r
#endif\r
\r
+#ifndef tracePEND_FUNC_CALL\r
+ #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret)\r
+#endif\r
+\r
+#ifndef tracePEND_FUNC_CALL_FROM_ISR\r
+ #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret)\r
+#endif \r
+\r
+#ifndef traceQUEUE_REGISTRY_ADD\r
+ #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName)\r
+#endif\r
+\r
#ifndef configGENERATE_RUN_TIME_STATS\r
#define configGENERATE_RUN_TIME_STATS 0\r
#endif\r
/* For internal use only. */\r
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet );\r
\r
+#if (configUSE_TRACE_FACILITY == 1)\r
+ UBaseType_t uxEventGroupGetNumber( void* xEventGroup );\r
+#endif\r
\r
#ifdef __cplusplus\r
}\r
void vAFunction( void *pvParameters )\r
{\r
char cValueToPost;\r
- const TickType_t xBlockTime = ( TickType_t )0xff;\r
+ const TickType_t xTicksToWait = ( TickType_t )0xff;\r
\r
// Create a queue capable of containing 10 characters.\r
xQueue = xQueueCreate( 10, sizeof( char ) );\r
// ...\r
\r
// Post some characters that will be used within an ISR. If the queue\r
- // is full then this task will block for xBlockTime ticks.\r
+ // is full then this task will block for xTicksToWait ticks.\r
cValueToPost = 'a';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );\r
cValueToPost = 'b';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );\r
\r
// ... keep posting characters ... this task may block when the queue\r
// becomes full.\r
\r
cValueToPost = 'c';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );\r
}\r
\r
// ISR that outputs all the characters received on the queue.\r
* For internal use only. Use xSemaphoreTakeMutexRecursive() or\r
* xSemaphoreGiveMutexRecursive() instead of calling these functions directly.\r
*/\r
-BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) PRIVILEGED_FUNCTION;\r
+BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION;\r
\r
/*\r
*\r
* @param xQueueSet The queue set on which the task will (potentially) block.\r
*\r
- * @param xBlockTimeTicks The maximum time, in ticks, that the calling task will\r
+ * @param xTicksToWait The maximum time, in ticks, that the calling task will\r
* remain in the Blocked state (with other tasks executing) to wait for a member\r
* of the queue set to be ready for a successful queue read or semaphore take\r
* operation.\r
* in the queue set that is available, or NULL if no such queue or semaphore\r
* exists before before the specified block time expires.\r
*/\r
-QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xBlockTimeTicks ) PRIVILEGED_FUNCTION;\r
+QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* A version of xQueueSelectFromSet() that can be used from an ISR.\r
as defined below. The commands that are sent from interrupts must use the\r
highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task\r
or interrupt version of the queue send function should be used. */\r
-#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )\r
-#define tmrCOMMAND_START ( ( BaseType_t ) 0 )\r
-#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 1 )\r
-#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 )\r
-#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 )\r
-#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 )\r
-#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 )\r
+#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )\r
+#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )\r
+#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )\r
+#define tmrCOMMAND_START ( ( BaseType_t ) 1 )\r
+#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 )\r
+#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 )\r
+#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 )\r
+#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 )\r
\r
-#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 )\r
-#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 7 )\r
-#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 8 )\r
-#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 9 )\r
+#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 )\r
+#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 )\r
+#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 )\r
+#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 )\r
\r
\r
/**\r
*/\r
typedef void * TimerHandle_t;\r
\r
-/* \r
- * Defines the prototype to which timer callback functions must conform. \r
+/*\r
+ * Defines the prototype to which timer callback functions must conform.\r
*/\r
typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );\r
\r
-/* \r
- * Defines the prototype to which functions used with the \r
+/*\r
+ * Defines the prototype to which functions used with the\r
* xTimerPendFunctionCallFromISR() function must conform.\r
*/\r
typedef void (*PendedFunction_t)( void *, uint32_t );\r
TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );\r
\r
/**\r
- * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xBlockTime );\r
+ * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );\r
*\r
* Timer functionality is provided by a timer service/daemon task. Many of the\r
* public FreeRTOS timer API functions send commands to the timer service task\r
*\r
* @param xTimer The handle of the timer being started/restarted.\r
*\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
* be held in the Blocked state to wait for the start command to be successfully\r
* sent to the timer command queue, should the queue already be full when\r
- * xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called\r
+ * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called\r
* before the scheduler is started.\r
*\r
* @return pdFAIL will be returned if the start command could not be sent to\r
- * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
+ * the timer command queue even after xTicksToWait ticks had passed. pdPASS will\r
* be returned if the command was successfully sent to the timer command queue.\r
* When the command is actually processed will depend on the priority of the\r
* timer service/daemon task relative to other tasks in the system, although the\r
* See the xTimerCreate() API function example usage scenario.\r
*\r
*/\r
-#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )\r
+#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )\r
\r
/**\r
- * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xBlockTime );\r
+ * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );\r
*\r
* Timer functionality is provided by a timer service/daemon task. Many of the\r
* public FreeRTOS timer API functions send commands to the timer service task\r
*\r
* @param xTimer The handle of the timer being stopped.\r
*\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
* be held in the Blocked state to wait for the stop command to be successfully\r
* sent to the timer command queue, should the queue already be full when\r
- * xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called\r
+ * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called\r
* before the scheduler is started.\r
*\r
* @return pdFAIL will be returned if the stop command could not be sent to\r
- * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
+ * the timer command queue even after xTicksToWait ticks had passed. pdPASS will\r
* be returned if the command was successfully sent to the timer command queue.\r
* When the command is actually processed will depend on the priority of the\r
* timer service/daemon task relative to other tasks in the system. The timer\r
* See the xTimerCreate() API function example usage scenario.\r
*\r
*/\r
-#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) )\r
+#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )\r
\r
/**\r
* BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,\r
* TickType_t xNewPeriod,\r
- * TickType_t xBlockTime );\r
+ * TickType_t xTicksToWait );\r
*\r
* Timer functionality is provided by a timer service/daemon task. Many of the\r
* public FreeRTOS timer API functions send commands to the timer service task\r
* ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than\r
* or equal to 1000.\r
*\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
* be held in the Blocked state to wait for the change period command to be\r
* successfully sent to the timer command queue, should the queue already be\r
- * full when xTimerChangePeriod() was called. xBlockTime is ignored if\r
+ * full when xTimerChangePeriod() was called. xTicksToWait is ignored if\r
* xTimerChangePeriod() is called before the scheduler is started.\r
*\r
* @return pdFAIL will be returned if the change period command could not be\r
- * sent to the timer command queue even after xBlockTime ticks had passed.\r
+ * sent to the timer command queue even after xTicksToWait ticks had passed.\r
* pdPASS will be returned if the command was successfully sent to the timer\r
* command queue. When the command is actually processed will depend on the\r
* priority of the timer service/daemon task relative to other tasks in the\r
* }\r
* @endverbatim\r
*/\r
- #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) )\r
+ #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) )\r
\r
/**\r
- * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xBlockTime );\r
+ * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );\r
*\r
* Timer functionality is provided by a timer service/daemon task. Many of the\r
* public FreeRTOS timer API functions send commands to the timer service task\r
*\r
* @param xTimer The handle of the timer being deleted.\r
*\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
* be held in the Blocked state to wait for the delete command to be\r
* successfully sent to the timer command queue, should the queue already be\r
- * full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete()\r
+ * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete()\r
* is called before the scheduler is started.\r
*\r
* @return pdFAIL will be returned if the delete command could not be sent to\r
- * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
+ * the timer command queue even after xTicksToWait ticks had passed. pdPASS will\r
* be returned if the command was successfully sent to the timer command queue.\r
* When the command is actually processed will depend on the priority of the\r
* timer service/daemon task relative to other tasks in the system. The timer\r
*\r
* See the xTimerChangePeriod() API function example usage scenario.\r
*/\r
-#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) )\r
+#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )\r
\r
/**\r
- * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xBlockTime );\r
+ * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );\r
*\r
* Timer functionality is provided by a timer service/daemon task. Many of the\r
* public FreeRTOS timer API functions send commands to the timer service task\r
*\r
* @param xTimer The handle of the timer being reset/started/restarted.\r
*\r
- * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
* be held in the Blocked state to wait for the reset command to be successfully\r
* sent to the timer command queue, should the queue already be full when\r
- * xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called\r
+ * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called\r
* before the scheduler is started.\r
*\r
* @return pdFAIL will be returned if the reset command could not be sent to\r
- * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
+ * the timer command queue even after xTicksToWait ticks had passed. pdPASS will\r
* be returned if the command was successfully sent to the timer command queue.\r
* When the command is actually processed will depend on the priority of the\r
* timer service/daemon task relative to other tasks in the system, although the\r
* }\r
* @endverbatim\r
*/\r
-#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )\r
+#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )\r
\r
/**\r
* BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,\r
*\r
*\r
* Used from application interrupt service routines to defer the execution of a\r
- * function to the RTOS daemon task (the timer service task, hence this function \r
+ * function to the RTOS daemon task (the timer service task, hence this function\r
* is implemented in timers.c and is prefixed with 'Timer').\r
*\r
* Ideally an interrupt service routine (ISR) is kept as short as possible, but\r
* sometimes an ISR either has a lot of processing to do, or needs to perform\r
- * processing that is not deterministic. In these cases \r
- * xTimerPendFunctionCallFromISR() can be used to defer processing of a function \r
+ * processing that is not deterministic. In these cases\r
+ * xTimerPendFunctionCallFromISR() can be used to defer processing of a function\r
* to the RTOS daemon task.\r
*\r
* A mechanism is provided that allows the interrupt to return directly to the\r
*/\r
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken );\r
\r
+ /**\r
+ * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,\r
+ * void *pvParameter1,\r
+ * uint32_t ulParameter2,\r
+ * TickType_t xTicksToWait );\r
+ *\r
+ *\r
+ * Used to defer the execution of a function to the RTOS daemon task (the timer\r
+ * service task, hence this function is implemented in timers.c and is prefixed\r
+ * with 'Timer').\r
+ *\r
+ * @param xFunctionToPend The function to execute from the timer service/\r
+ * daemon task. The function must conform to the PendedFunction_t\r
+ * prototype.\r
+ *\r
+ * @param pvParameter1 The value of the callback function's first parameter.\r
+ * The parameter has a void * type to allow it to be used to pass any type.\r
+ * For example, unsigned longs can be cast to a void *, or the void * can be\r
+ * used to point to a structure.\r
+ *\r
+ * @param ulParameter2 The value of the callback function's second parameter.\r
+ *\r
+ * @param xTicksToWait Calling this function will result in a message being\r
+ * sent to the timer daemon task on a queue. xTicksToWait is the amount of\r
+ * time the calling task should remain in the Blocked state (so not using any\r
+ * processing time) for space to become available on the timer queue if the\r
+ * queue is found to be full.\r
+ *\r
+ * @return pdPASS is returned if the message was successfully sent to the\r
+ * timer daemon task, otherwise pdFALSE is returned.\r
+ *\r
+ */\r
+BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait );\r
+\r
/*\r
* Functions beyond this part are not part of the public API and are intended\r
* for use by the kernel only.\r
*/\r
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;\r
-BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xBlockTime ) PRIVILEGED_FUNCTION;\r
+BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
\r
#ifdef __cplusplus\r
}\r
/*\r
- FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. \r
+ FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
*/\r
extern void vPortStartFirstTask( void );\r
\r
+/*\r
+ * Used to catch tasks that attempt to return from their implementing function.\r
+ */\r
+static void prvTaskExitError( void );\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
{\r
uint32_t *pulLocal;\r
\r
+ /* With large code and large data sizeof( StackType_t ) == 2, and\r
+ sizeof( StackType_t * ) == 4. With small code and small data\r
+ sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */\r
+\r
#if __DATA_MODEL__ == __DATA_MODEL_FAR__\r
{\r
- /* Parameters are passed in on the stack, and written using a 32bit value\r
+ /* Parameters are passed in on the stack, and written using a 32-bit value\r
hence a space is left for the second two bytes. */\r
pxTopOfStack--;\r
\r
*pulLocal = ( uint32_t ) pvParameters;\r
pxTopOfStack--;\r
\r
- /* These values are just spacers. The return address of the function\r
- would normally be written here. */\r
- *pxTopOfStack = ( StackType_t ) 0xcdcd;\r
+ /* The return address, leaving space for the first two bytes of the\r
+ 32-bit value. See the comments above the prvTaskExitError() prototype\r
+ at the top of this file. */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( StackType_t ) 0xcdcd;\r
+ pulLocal = ( uint32_t * ) pxTopOfStack;\r
+ *pulLocal = ( uint32_t ) prvTaskExitError;\r
pxTopOfStack--;\r
\r
- /* The start address / PSW value is also written in as a 32bit value,\r
+ /* The start address / PSW value is also written in as a 32-bit value,\r
so leave a space for the second two bytes. */\r
pxTopOfStack--;\r
\r
}\r
#else\r
{\r
- /* Task function address is written to the stack first. As it is\r
- written as a 32bit value a space is left on the stack for the second\r
- two bytes. */\r
+ /* The return address, leaving space for the first two bytes of the\r
+ 32-bit value. See the comments above the prvTaskExitError() prototype\r
+ at the top of this file. */\r
+ pxTopOfStack--;\r
+ pulLocal = ( uint32_t * ) pxTopOfStack;\r
+ *pulLocal = ( uint32_t ) prvTaskExitError;\r
+ pxTopOfStack--;\r
+\r
+ /* Task function. Again as it is written as a 32-bit value a space is\r
+ left on the stack for the second two bytes. */\r
pxTopOfStack--;\r
\r
/* Task function start address combined with the PSW. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvTaskExitError( void )\r
+{\r
+ /* A function that implements a task must not exit or attempt to return to\r
+ its caller as there is nothing to return to. If a task wants to exit it\r
+ should instead call vTaskDelete( NULL ).\r
+\r
+ Artificially force an assert() to be triggered if configASSERT() is\r
+ defined, then stop here so application writers can catch the error. */\r
+ configASSERT( usCriticalNesting == ~0U );\r
+ portDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
BaseType_t xPortStartScheduler( void )\r
{\r
/* Setup the hardware to generate the tick. Interrupts are disabled when\r
\r
#if ( configUSE_RECURSIVE_MUTEXES == 1 )\r
\r
- BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime )\r
+ BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait )\r
{\r
BaseType_t xReturn;\r
Queue_t * const pxMutex = ( Queue_t * ) xMutex;\r
}\r
else\r
{\r
- xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );\r
+ xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE );\r
\r
/* pdPASS will only be returned if we successfully obtained the mutex,\r
we may have blocked to reach here. */\r
/* Store the information on this queue. */\r
xQueueRegistry[ ux ].pcQueueName = pcQueueName;\r
xQueueRegistry[ ux ].xHandle = xQueue;\r
+\r
+ traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName );\r
break;\r
}\r
else\r
{\r
BaseType_t xReturn;\r
\r
- if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL )\r
- {\r
- /* Cannot add a queue/semaphore to more than one queue set. */\r
- xReturn = pdFAIL;\r
- }\r
- else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 )\r
- {\r
- /* Cannot add a queue/semaphore to a queue set if there are already\r
- items in the queue/semaphore. */\r
- xReturn = pdFAIL;\r
- }\r
- else\r
+ taskENTER_CRITICAL();\r
{\r
- taskENTER_CRITICAL();\r
+ if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL )\r
+ {\r
+ /* Cannot add a queue/semaphore to more than one queue set. */\r
+ xReturn = pdFAIL;\r
+ }\r
+ else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 )\r
+ {\r
+ /* Cannot add a queue/semaphore to a queue set if there are already\r
+ items in the queue/semaphore. */\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
{\r
( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet;\r
+ xReturn = pdPASS;\r
}\r
- taskEXIT_CRITICAL();\r
- xReturn = pdPASS;\r
}\r
+ taskEXIT_CRITICAL();\r
\r
return xReturn;\r
}\r
\r
#if ( configUSE_QUEUE_SETS == 1 )\r
\r
- QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xBlockTimeTicks )\r
+ QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait )\r
{\r
QueueSetMemberHandle_t xReturn = NULL;\r
\r
- ( void ) xQueueGenericReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */\r
+ ( void ) xQueueGenericReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */\r
return xReturn;\r
}\r
\r
#include "queue.h"\r
#include "timers.h"\r
\r
-#if ( INCLUDE_xTimerPendFunctionCallFromISR == 1 ) && ( configUSE_TIMERS == 0 )\r
- #error configUSE_TIMERS must be set to 1 to make the INCLUDE_xTimerPendFunctionCallFromISR() function available.\r
+#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 )\r
+ #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.\r
#endif\r
\r
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the\r
\r
/* Don't include xCallbackParameters if it is not going to be used as\r
it makes the structure (and therefore the timer queue) larger. */\r
- #if ( INCLUDE_xTimerPendFunctionCallFromISR == 1 )\r
+ #if ( INCLUDE_xTimerPendFunctionCall == 1 )\r
CallbackParameters_t xCallbackParameters;\r
- #endif /* INCLUDE_xTimerPendFunctionCallFromISR */\r
+ #endif /* INCLUDE_xTimerPendFunctionCall */\r
} u;\r
} DaemonTaskMessage_t;\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xBlockTime )\r
+BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait )\r
{\r
BaseType_t xReturn = pdFAIL;\r
DaemonTaskMessage_t xMessage;\r
{\r
if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )\r
{\r
- xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime );\r
+ xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );\r
}\r
else\r
{\r
\r
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. */\r
{\r
- #if ( INCLUDE_xTimerPendFunctionCallFromISR == 1 )\r
+ #if ( INCLUDE_xTimerPendFunctionCall == 1 )\r
{\r
- if( xMessage.xMessageID == tmrCOMMAND_EXECUTE_CALLBACK )\r
+ /* Negative commands are pended function calls rather than timer\r
+ commands. */\r
+ if( xMessage.xMessageID < 0 )\r
{\r
const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters );\r
\r
mtCOVERAGE_TEST_MARKER();\r
}\r
}\r
- #endif /* INCLUDE_xTimerPendFunctionCallFromISR */\r
+ #endif /* INCLUDE_xTimerPendFunctionCall */\r
\r
- if( xMessage.xMessageID != tmrCOMMAND_EXECUTE_CALLBACK )\r
+ /* Commands that are positive are timer commands rather than pended\r
+ function calls. */\r
+ if( xMessage.xMessageID >= 0 )\r
{\r
/* The messages uses the xTimerParameters member to work on a\r
software timer. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#if( INCLUDE_xTimerPendFunctionCallFromISR == 1 )\r
+#if( INCLUDE_xTimerPendFunctionCall == 1 )\r
\r
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken )\r
{\r
\r
/* Complete the message with the function parameters and post it to the\r
daemon task. */\r
- xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK;\r
+ xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;\r
xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;\r
xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;\r
xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;\r
\r
xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );\r
+ \r
+ tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn );\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* INCLUDE_xTimerPendFunctionCall */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( INCLUDE_xTimerPendFunctionCall == 1 )\r
+\r
+ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait )\r
+ {\r
+ DaemonTaskMessage_t xMessage;\r
+ BaseType_t xReturn;\r
+\r
+ /* Complete the message with the function parameters and post it to the\r
+ daemon task. */\r
+ xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK;\r
+ xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;\r
+ xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;\r
+ xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;\r
+\r
+ xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );\r
\r
+ tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn );\r
+ \r
return xReturn;\r
}\r
\r
-#endif /* INCLUDE_xTimerPendFunctionCallFromISR */\r
+#endif /* INCLUDE_xTimerPendFunctionCall */\r
/*-----------------------------------------------------------*/\r
\r
/* This entire source file will be skipped if the application is not configured\r