From cbaff6b70835fadb84103b6ddf54679aff0f8936 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sat, 12 Apr 2008 09:48:40 +0000 Subject: [PATCH] Update prototypes and macros for the new xQueueSendFromISR() function and the task hook feature. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@302 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/include/FreeRTOS.h | 28 ++++++++ Source/include/projdefs.h | 2 +- Source/include/queue.h | 139 +++++++++++++++----------------------- Source/include/semphr.h | 24 +++---- Source/include/task.h | 25 ++++++- 5 files changed, 120 insertions(+), 98 deletions(-) diff --git a/Source/include/FreeRTOS.h b/Source/include/FreeRTOS.h index 6c47cc0b4..f69fc02f5 100644 --- a/Source/include/FreeRTOS.h +++ b/Source/include/FreeRTOS.h @@ -66,6 +66,9 @@ #include "portable.h" +/* Defines the prototype to which the application task hook function must +conform. */ +typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); @@ -125,6 +128,10 @@ #error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif +#ifndef configUSE_APPLICATION_TASK_HOOK + #define configUSE_APPLICATION_TASK_HOOK 0 +#endif + #ifndef INCLUDE_uxTaskGetStackHighWaterMark #define INCLUDE_uxTaskGetStackHighWaterMark 0 #endif @@ -149,6 +156,27 @@ #define portCRITICAL_NESTING_IN_TCB 0 #endif +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #undef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 1 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + #if ( configUSE_MUTEXES == 1 ) /* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism within the mutex implementation so must be available if mutexes are used. */ diff --git a/Source/include/projdefs.h b/Source/include/projdefs.h index 4c755bf8d..9b78d4e7f 100644 --- a/Source/include/projdefs.h +++ b/Source/include/projdefs.h @@ -50,7 +50,7 @@ #ifndef PROJDEFS_H #define PROJDEFS_H -/* Defines to prototype to which task functions must conform. */ +/* Defines the prototype to which task functions must conform. */ typedef void (*pdTASK_CODE)( void * ); #define pdTRUE ( 1 ) diff --git a/Source/include/queue.h b/Source/include/queue.h index 9e299aae3..6b1c4fd48 100644 --- a/Source/include/queue.h +++ b/Source/include/queue.h @@ -789,15 +789,14 @@ void vQueueDelete( xQueueHandle xQueue ); * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * - * @param cTaskPreviouslyWoken This is included so an ISR can post onto - * the same queue multiple times from a single interrupt. The first call - * should always pass in pdFALSE. Subsequent calls should pass in - * the value returned from the previous call. See the file serial .c in the - * PC port for a good example of this mechanism. + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. * - * @return pdTRUE if a task was woken by posting onto the queue. This is - * used by the ISR to determine if a context switch may be required following - * the ISR. + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value * per call): @@ -805,10 +804,10 @@ void vQueueDelete( xQueueHandle xQueue ); void vBufferISR( void ) { portCHAR cIn; - portBASE_TYPE xTaskWokenByPost; + portBASE_TYPE xHigherPrioritTaskWoken; // We have not woken a task at the start of the ISR. - cTaskWokenByPost = pdFALSE; + xHigherPriorityTaskWoken = pdFALSE; // Loop until the buffer is empty. do @@ -816,19 +815,13 @@ void vQueueDelete( xQueueHandle xQueue ); // Obtain a byte from the buffer. cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); - // Post the byte. The first time round the loop cTaskWokenByPost - // will be pdFALSE. If the queue send causes a task to wake we do - // not want the task to run until we have finished the ISR, so - // xQueueSendFromISR does not cause a context switch. Also we - // don't want subsequent posts to wake any other tasks, so we store - // the return value back into cTaskWokenByPost so xQueueSendFromISR - // knows not to wake any task the next iteration of the loop. - xTaskWokenByPost = xQueueSendToFrontFromISR( xRxQueue, &cIn, cTaskWokenByPost ); + // Post the byte. + xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); } while( portINPUT_BYTE( BUFFER_COUNT ) ); // Now the buffer is empty we can switch context if necessary. - if( cTaskWokenByPost ) + if( xHigherPriorityTaskWoken ) { taskYIELD (); } @@ -838,7 +831,7 @@ void vQueueDelete( xQueueHandle xQueue ); * \defgroup xQueueSendFromISR xQueueSendFromISR * \ingroup QueueManagement */ -#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken, queueSEND_TO_FRONT ) +#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_FRONT ) /** @@ -867,15 +860,14 @@ void vQueueDelete( xQueueHandle xQueue ); * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * - * @param cTaskPreviouslyWoken This is included so an ISR can post onto - * the same queue multiple times from a single interrupt. The first call - * should always pass in pdFALSE. Subsequent calls should pass in - * the value returned from the previous call. See the file serial .c in the - * PC port for a good example of this mechanism. + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. * - * @return pdTRUE if a task was woken by posting onto the queue. This is - * used by the ISR to determine if a context switch may be required following - * the ISR. + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value * per call): @@ -883,10 +875,10 @@ void vQueueDelete( xQueueHandle xQueue ); void vBufferISR( void ) { portCHAR cIn; - portBASE_TYPE xTaskWokenByPost; + portBASE_TYPE xHigherPriorityTaskWoken; // We have not woken a task at the start of the ISR. - cTaskWokenByPost = pdFALSE; + xHigherPriorityTaskWoken = pdFALSE; // Loop until the buffer is empty. do @@ -894,19 +886,13 @@ void vQueueDelete( xQueueHandle xQueue ); // Obtain a byte from the buffer. cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); - // Post the byte. The first time round the loop cTaskWokenByPost - // will be pdFALSE. If the queue send causes a task to wake we do - // not want the task to run until we have finished the ISR, so - // xQueueSendFromISR does not cause a context switch. Also we - // don't want subsequent posts to wake any other tasks, so we store - // the return value back into cTaskWokenByPost so xQueueSendFromISR - // knows not to wake any task the next iteration of the loop. - xTaskWokenByPost = xQueueSendToBackFromISR( xRxQueue, &cIn, cTaskWokenByPost ); + // Post the byte. + xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); } while( portINPUT_BYTE( BUFFER_COUNT ) ); // Now the buffer is empty we can switch context if necessary. - if( cTaskWokenByPost ) + if( xHigherPriorityTaskWoken ) { taskYIELD (); } @@ -916,7 +902,7 @@ void vQueueDelete( xQueueHandle xQueue ); * \defgroup xQueueSendFromISR xQueueSendFromISR * \ingroup QueueManagement */ -#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken, queueSEND_TO_BACK ) +#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) /** * queue. h @@ -947,15 +933,14 @@ void vQueueDelete( xQueueHandle xQueue ); * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * - * @param cTaskPreviouslyWoken This is included so an ISR can post onto - * the same queue multiple times from a single interrupt. The first call - * should always pass in pdFALSE. Subsequent calls should pass in - * the value returned from the previous call. See the file serial .c in the - * PC port for a good example of this mechanism. + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. * - * @return pdTRUE if a task was woken by posting onto the queue. This is - * used by the ISR to determine if a context switch may be required following - * the ISR. + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value * per call): @@ -963,10 +948,10 @@ void vQueueDelete( xQueueHandle xQueue ); void vBufferISR( void ) { portCHAR cIn; - portBASE_TYPE xTaskWokenByPost; + portBASE_TYPE xHigherPriorityTaskWoken; // We have not woken a task at the start of the ISR. - cTaskWokenByPost = pdFALSE; + xHigherPriorityTaskWoken = pdFALSE; // Loop until the buffer is empty. do @@ -974,19 +959,13 @@ void vQueueDelete( xQueueHandle xQueue ); // Obtain a byte from the buffer. cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); - // Post the byte. The first time round the loop cTaskWokenByPost - // will be pdFALSE. If the queue send causes a task to wake we do - // not want the task to run until we have finished the ISR, so - // xQueueSendFromISR does not cause a context switch. Also we - // don't want subsequent posts to wake any other tasks, so we store - // the return value back into cTaskWokenByPost so xQueueSendFromISR - // knows not to wake any task the next iteration of the loop. - xTaskWokenByPost = xQueueSendFromISR( xRxQueue, &cIn, cTaskWokenByPost ); + // Post the byte. + xTaskWokenByPost = xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); } while( portINPUT_BYTE( BUFFER_COUNT ) ); // Now the buffer is empty we can switch context if necessary. - if( cTaskWokenByPost ) + if( xHigherPriorityTaskWoken ) { taskYIELD (); } @@ -996,7 +975,7 @@ void vQueueDelete( xQueueHandle xQueue ); * \defgroup xQueueSendFromISR xQueueSendFromISR * \ingroup QueueManagement */ -#define xQueueSendFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken, queueSEND_TO_BACK ) +#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) /** * queue. h @@ -1004,7 +983,7 @@ void vQueueDelete( xQueueHandle xQueue ); portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, - portBASE_TYPE xTaskPreviouslyWoken + portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ); @@ -1027,19 +1006,18 @@ void vQueueDelete( xQueueHandle xQueue ); * queue was created, so this many bytes will be copied from pvItemToQueue * into the queue storage area. * - * @param cTaskPreviouslyWoken This is included so an ISR can post onto - * the same queue multiple times from a single interrupt. The first call - * should always pass in pdFALSE. Subsequent calls should pass in - * the value returned from the previous call. See the file serial .c in the - * PC port for a good example of this mechanism. + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. * * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the * item at the back of the queue, or queueSEND_TO_FRONT to place the item * at the front of the queue (for high priority messages). * - * @return pdTRUE if a task was woken by posting onto the queue. This is - * used by the ISR to determine if a context switch may be required following - * the ISR. + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. * * Example usage for buffered IO (where the ISR can obtain more than one value * per call): @@ -1047,10 +1025,10 @@ void vQueueDelete( xQueueHandle xQueue ); void vBufferISR( void ) { portCHAR cIn; - portBASE_TYPE xTaskWokenByPost; + portBASE_TYPE xHigherPriorityTaskWokenByPost; // We have not woken a task at the start of the ISR. - cTaskWokenByPost = pdFALSE; + xHigherPriorityTaskWokenByPost = pdFALSE; // Loop until the buffer is empty. do @@ -1058,21 +1036,16 @@ void vQueueDelete( xQueueHandle xQueue ); // Obtain a byte from the buffer. cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); - // Post the byte. The first time round the loop cTaskWokenByPost - // will be pdFALSE. If the queue send causes a task to wake we do - // not want the task to run until we have finished the ISR, so - // xQueueSendFromISR does not cause a context switch. Also we - // don't want subsequent posts to wake any other tasks, so we store - // the return value back into cTaskWokenByPost so xQueueSendFromISR - // knows not to wake any task the next iteration of the loop. - xTaskWokenByPost = xQueueGenericSendFromISR( xRxQueue, &cIn, cTaskWokenByPost, queueSEND_TO_BACK ); + // Post each byte. + xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK ); } while( portINPUT_BYTE( BUFFER_COUNT ) ); - // Now the buffer is empty we can switch context if necessary. - if( cTaskWokenByPost ) + // Now the buffer is empty we can switch context if necessary. Note that the + // name of the yield function required is port specific. + if( xHigherPriorityTaskWokenByPost ) { - taskYIELD (); + taskYIELD_YIELD_FROM_ISR(); } } @@ -1080,7 +1053,7 @@ void vQueueDelete( xQueueHandle xQueue ); * \defgroup xQueueSendFromISR xQueueSendFromISR * \ingroup QueueManagement */ -signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition ); +signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ); /** * queue. h diff --git a/Source/include/semphr.h b/Source/include/semphr.h index e53dda77f..accfa41a2 100644 --- a/Source/include/semphr.h +++ b/Source/include/semphr.h @@ -460,15 +460,13 @@ typedef xQueueHandle xSemaphoreHandle; * @param xSemaphore A handle to the semaphore being released. This is the * handle returned when the semaphore was created. * - * @param sTaskPreviouslyWoken This is included so an ISR can make multiple calls - * to xSemaphoreGiveFromISR () from a single interrupt. The first call - * should always pass in pdFALSE. Subsequent calls should pass in - * the value returned from the previous call. See the file serial .c in the - * PC port for a good example of using xSemaphoreGiveFromISR (). + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. * - * @return pdTRUE if a task was woken by releasing the semaphore. This is - * used by the ISR to determine if a context switch may be required following - * the ISR. + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. * * Example usage:
@@ -503,25 +501,25 @@ typedef xQueueHandle xSemaphoreHandle;
  void vTimerISR( void * pvParameters )
  {
  static unsigned portCHAR ucLocalTickCount = 0;
- static portBASE_TYPE xTaskWoken;
+ static portBASE_TYPE xHigherPriorityTaskWoken;
 
     // A timer tick has occurred.
 
     // ... Do other time functions.
 
     // Is it time for vATask () to run?
-	xTaskWoken = pdFALSE;
+	xHigherPriorityTaskWoken = pdFALSE;
     ucLocalTickCount++;
     if( ucLocalTickCount >= TICKS_TO_WAIT )
     {
         // Unblock the task by releasing the semaphore.
-        xTaskWoken = xSemaphoreGiveFromISR( xSemaphore, xTaskWoken );
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
 
         // Reset the count so we release the semaphore again in 10 ticks time.
         ucLocalTickCount = 0;
     }
 
-    if( xTaskWoken != pdFALSE )
+    if( xHigherPriorityTaskWoken != pdFALSE )
     {
         // We can force a context switch here.  Context switching from an
         // ISR uses port specific syntax.  Check the demo task for your port
@@ -532,7 +530,7 @@ typedef xQueueHandle xSemaphoreHandle;
  * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
  * \ingroup Semaphores
  */
-#define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken )			xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken, queueSEND_TO_BACK )
+#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )			xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
 
 /**
  * semphr. h
diff --git a/Source/include/task.h b/Source/include/task.h
index fa5f6adbf..234118395 100644
--- a/Source/include/task.h
+++ b/Source/include/task.h
@@ -66,7 +66,7 @@ extern "C" {
  * MACROS AND DEFINITIONS
  *----------------------------------------------------------*/
 
-#define tskKERNEL_VERSION_NUMBER "V4.7.2"
+#define tskKERNEL_VERSION_NUMBER "V5.0.0"
 
 /**
  * task. h
@@ -893,6 +893,29 @@ unsigned portLONG ulTaskEndTrace( void );
  */
 unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
 
+/**
+ * task.h
+ * 
void vTaskSetApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ +void vTaskSetApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ); + +/** + * task.h + *
portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. + */ +portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ); + + /*----------------------------------------------------------- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES *----------------------------------------------------------*/ -- 2.39.5