diff --git a/Source/include/FreeRTOS.h b/Source/include/FreeRTOS.h index 6c47cc0b43..f69fc02f59 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 4c755bf8df..9b78d4e7ff 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 9e299aae3c..6b1c4fd487 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 e53dda77f8..accfa41a22 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 fa5f6adbf6..2341183953 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
*----------------------------------------------------------*/