Implement xTaskResumeFromISR.

This commit is contained in:
Richard Barry 2006-08-11 10:02:38 +00:00
parent 430893f5f8
commit 58a357e6e6
2 changed files with 59 additions and 29 deletions

View file

@ -533,6 +533,26 @@ void vTaskSuspend( xTaskHandle pxTaskToSuspend );
*/ */
void vTaskResume( xTaskHandle pxTaskToResume ); void vTaskResume( xTaskHandle pxTaskToResume );
/**
* task. h
* <pre>void xTaskResumeFromISR( xTaskHandle pxTaskToResume );</pre>
*
* 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 * SCHEDULER CONTROL
*----------------------------------------------------------*/ *----------------------------------------------------------*/

View file

@ -175,6 +175,7 @@ Changed from V4.0.4
+ vTaskPrioritySet() and vTaskResume() no longer use the event list item. + vTaskPrioritySet() and vTaskResume() no longer use the event list item.
This has not been necessary since V4.0.1 when the xMissedYield handling This has not been necessary since V4.0.1 when the xMissedYield handling
was added. was added.
+ Implement xTaskResumeFromISR().
*/ */
#include <stdio.h> #include <stdio.h>
@ -211,6 +212,9 @@ Changed from V4.0.4
#define configMAX_TASK_NAME_LEN 1 #define configMAX_TASK_NAME_LEN 1
#endif #endif
#ifndef INCLUDE_xTaskResumeFromISR
#define INCLUDE_xTaskResumeFromISR 1
#endif
/* /*
* Task control block. A task control block (TCB) is allocated to each task, * 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? */ /* Is the task we are attempting to resume actually suspended? */
if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )
{ {
/* As we are in a critical section we can access the ready /* Has the task already been resumed from within an ISR? */
lists even if the scheduler is suspended. */ if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )
vListRemove( &( pxTCB->xGenericListItem ) ); {
prvAddTaskToReadyQueue( pxTCB ); /* 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. */ /* We may have just resumed a higher priority task. */
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
{ {
/* This yield may not cause the task just resumed to run, but /* This yield may not cause the task just resumed to run, but
will leave the lists in the correct state for the next yield. */ will leave the lists in the correct state for the next yield. */
taskYIELD(); taskYIELD();
}
} }
} }
} }
@ -953,33 +961,35 @@ 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 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? */ /* 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 ) /* Has the task already been resumed from within an ISR? */
if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )
{ {
xYieldRequired = ( pxTaskToResume->uxPriority >= pxCurrentTCB->uxPriority ); if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
vListRemove( &( pxTaskToResume->xGenericListItem ) ); {
prvAddTaskToReadyQueue( pxTaskToResume ); 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
{
/* 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 ) );
}
}
else
{
xYieldRequired = pdFALSE;
} }
return xYieldRequired; return xYieldRequired;