From 116ea653fee082749a0837d98dca8cbc37d3fc24 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Fri, 11 Aug 2006 10:02:38 +0000 Subject: [PATCH] Implement xTaskResumeFromISR. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@22 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/include/task.h | 20 +++++++++++++ Source/tasks.c | 70 ++++++++++++++++++++++++------------------- 2 files changed, 60 insertions(+), 30 deletions(-) diff --git a/Source/include/task.h b/Source/include/task.h index c53864a46..74f44b6c7 100644 --- a/Source/include/task.h +++ b/Source/include/task.h @@ -533,6 +533,26 @@ void vTaskSuspend( xTaskHandle pxTaskToSuspend ); */ void vTaskResume( xTaskHandle pxTaskToResume ); +/** + * task. h + *
void xTaskResumeFromISR( xTaskHandle pxTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one of more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * @param pxTaskToResume Handle to the task being readied. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ); + /*----------------------------------------------------------- * SCHEDULER CONTROL *----------------------------------------------------------*/ diff --git a/Source/tasks.c b/Source/tasks.c index 7f60f8dea..0e4b1a151 100644 --- a/Source/tasks.c +++ b/Source/tasks.c @@ -175,6 +175,7 @@ Changed from V4.0.4 + vTaskPrioritySet() and vTaskResume() no longer use the event list item. This has not been necessary since V4.0.1 when the xMissedYield handling was added. + + Implement xTaskResumeFromISR(). */ #include @@ -211,6 +212,9 @@ Changed from V4.0.4 #define configMAX_TASK_NAME_LEN 1 #endif +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif /* * Task control block. A task control block (TCB) is allocated to each task, @@ -931,17 +935,21 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat /* Is the task we are attempting to resume actually suspended? */ if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) { - /* As we are in a critical section we can access the ready - lists even if the scheduler is suspended. */ - vListRemove( &( pxTCB->xGenericListItem ) ); - prvAddTaskToReadyQueue( pxTCB ); - - /* We may have just resumed a higher priority task. */ - if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) - { - /* This yield may not cause the task just resumed to run, but - will leave the lists in the correct state for the next yield. */ - taskYIELD(); + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE ) + { + /* As we are in a critical section we can access the ready + lists even if the scheduler is suspended. */ + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + + /* We may have just resumed a higher priority task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, but + will leave the lists in the correct state for the next yield. */ + taskYIELD(); + } } } } @@ -953,34 +961,36 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat /*-----------------------------------------------------------*/ -#if ( INCLUDE_vTaskResumeFromISR == 1 ) +#if ( INCLUDE_xTaskResumeFromISR == 1 ) portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) { - portBASE_TYPE xYieldRequired; + portBASE_TYPE xYieldRequired = pdFALSE; + tskTCB *pxTCB; + + pxTCB = ( tskTCB * ) pxTaskToResume; /* Is the task we are attempting to resume actually suspended? */ - if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTaskToResume->xGenericListItem ) ) != pdFALSE ) + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) { - if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) - { - xYieldRequired = ( pxTaskToResume->uxPriority >= pxCurrentTCB->uxPriority ); - vListRemove( &( pxTaskToResume->xGenericListItem ) ); - prvAddTaskToReadyQueue( pxTaskToResume ); - } - else + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE ) { - /* We cannot access the delayed or ready lists, so will hold this - task pending until the scheduler is resumed, at which point a - yield will be preformed if necessary. */ - xYieldRequired = pdFALSE; - vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTaskToResume->xEventListItem ) ); + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ); + vListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyQueue( pxTCB ); + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed, at which point a + yield will be preformed if necessary. */ + vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } } } - else - { - xYieldRequired = pdFALSE; - } return xYieldRequired; } -- 2.39.5