@ -153,17 +153,28 @@ Changes from V4.0.0
Changes from V4 .0 .1
+ The function vTaskList ( ) now suspends the scheduler rather than disabling
interrup s during the creation of the task list .
interrup t s during the creation of the task list .
+ Allow a task to delete itself by passing in its own handle . Previously
this could only be done by passing in NULL .
+ The tick hook function is now called only within a tick isr . Previously
it was also called when the tick function was called during the scheduler
unlocking process .
Changes from V4 .0 . 4
Changes from V4 .0 . 3
+ Extra checks have been placed in vTaskPrioritySet ( ) to avoid unnecessary
yields .
Changed from V4 .0 .4
+ Bug fix : The ' value ' of the event list item is updated when the priority
of a task is changed . Previously only the priority of the TCB itself was
changed .
+ When resuming a task a check is first made to see if the task is actually
suspended .
+ 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 .
*/
# include <stdio.h>
@ -290,28 +301,28 @@ static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
*/
# if ( configUSE_TRACE_FACILITY == 1 )
# define vWriteTraceToBuffer() \
{ \
if ( xTracing ) \
{ \
static unsigned portBASE_TYPE uxPreviousTask = 255 ; \
\
if ( uxPreviousTask ! = pxCurrentTCB - > uxTCBNumber ) \
{ \
if ( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \
{ \
uxPreviousTask = pxCurrentTCB - > uxTCBNumber ; \
# define vWriteTraceToBuffer() \
{ \
if ( xTracing ) \
{ \
static unsigned portBASE_TYPE uxPreviousTask = 255 ; \
\
if ( uxPreviousTask ! = pxCurrentTCB - > uxTCBNumber ) \
{ \
if ( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \
{ \
uxPreviousTask = pxCurrentTCB - > uxTCBNumber ; \
* ( unsigned portLONG * ) pcTraceBuffer = ( unsigned portLONG ) xTickCount ; \
pcTraceBuffer + = sizeof ( unsigned portLONG ) ; \
pcTraceBuffer + = sizeof ( unsigned portLONG ) ; \
* ( unsigned portLONG * ) pcTraceBuffer = ( unsigned portLONG ) uxPreviousTask ; \
pcTraceBuffer + = sizeof ( unsigned portLONG ) ; \
} \
else \
{ \
xTracing = pdFALSE ; \
} \
} \
} \
pcTraceBuffer + = sizeof ( unsigned portLONG ) ; \
} \
else \
{ \
xTracing = pdFALSE ; \
} \
} \
} \
}
# else
@ -335,8 +346,7 @@ static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
uxTopReadyPriority = pxTCB - > uxPriority ; \
} \
vListInsertEnd ( ( xList * ) & ( pxReadyTasksLists [ pxTCB - > uxPriority ] ) , & ( pxTCB - > xGenericListItem ) ) ; \
}
}
/*
* Macro that looks at the list of tasks that are currently delayed to see if
@ -346,24 +356,24 @@ static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
* once one tasks has been found whose timer has not expired we need not look
* any further down the list .
*/
# define prvCheckDelayedTasks() \
{ \
register tskTCB * pxTCB ; \
\
while ( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY ( pxDelayedTaskList ) ) ! = NULL ) \
{ \
if ( xTickCount < listGET_LIST_ITEM_VALUE ( & ( pxTCB - > xGenericListItem ) ) ) \
{ \
break ; \
} \
vListRemove ( & ( pxTCB - > xGenericListItem ) ) ; \
/* Is the task waiting on an event also? */ \
if ( pxTCB - > xEventListItem . pvContainer ) \
{ \
vListRemove ( & ( pxTCB - > xEventListItem ) ) ; \
} \
# define prvCheckDelayedTasks() \
{ \
register tskTCB * pxTCB ; \
\
while ( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY ( pxDelayedTaskList ) ) ! = NULL ) \
{ \
if ( xTickCount < listGET_LIST_ITEM_VALUE ( & ( pxTCB - > xGenericListItem ) ) ) \
{ \
break ; \
} \
vListRemove ( & ( pxTCB - > xGenericListItem ) ) ; \
/* Is the task waiting on an event also? */ \
if ( pxTCB - > xEventListItem . pvContainer ) \
{ \
vListRemove ( & ( pxTCB - > xEventListItem ) ) ; \
} \
prvAddTaskToReadyQueue ( pxTCB ) ; \
} \
} \
}
/*
@ -615,9 +625,12 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
taskEXIT_CRITICAL ( ) ;
/* Force a reschedule if we have just deleted the current task. */
if ( ( void * ) pxTaskToDelete = = NULL )
if ( xSchedulerRunning ! = pdFALSE )
{
taskYIELD ( ) ;
if ( ( void * ) pxTaskToDelete = = NULL )
{
taskYIELD ( ) ;
}
}
}
@ -831,6 +844,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
}
pxTCB - > uxPriority = uxNewPriority ;
listSET_LIST_ITEM_VALUE ( & ( pxTCB - > xEventListItem ) , configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) ;
/* If the task is in the blocked or suspended list we need do
nothing more than change it ' s priority variable . However , if
@ -838,19 +852,11 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
in the queue appropriate to its new priority . */
if ( listIS_CONTAINED_WITHIN ( & ( pxReadyTasksLists [ uxCurrentPriority ] ) , & ( pxTCB - > xGenericListItem ) ) )
{
if ( uxSchedulerSuspended = = ( unsigned portBASE_TYPE ) pdFALSE )
{
/* The task is currently in its ready list - remove before adding
it to it ' s new ready list . */
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 . */
vListInsertEnd ( ( xList * ) & ( xPendingReadyList ) , & ( pxTCB - > xEventListItem ) ) ;
}
/* The task is currently in its ready list - remove before adding
it to it ' s new ready list . As we are in a critical section we
can do this even if the scheduler is suspended . */
vListRemove ( & ( pxTCB - > xGenericListItem ) ) ;
prvAddTaskToReadyQueue ( pxTCB ) ;
}
if ( xYieldRequired = = pdTRUE )
@ -911,7 +917,6 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
void vTaskResume ( xTaskHandle pxTaskToResume )
{
tskTCB * pxTCB ;
portBASE_TYPE xYieldRequired ;
/* Remove the task from whichever list it is currently in, and place
it in the ready list . */
@ -923,30 +928,56 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
{
taskENTER_CRITICAL ( ) ;
{
if ( uxSchedulerSuspended = = ( unsigned portBASE_TYPE ) pdFALSE )
/* Is the task we are attempting to resume actually suspended? */
if ( listIS_CONTAINED_WITHIN ( & xSuspendedTaskList , & ( pxTCB - > xGenericListItem ) ) ! = pdFALSE )
{
xYieldRequired = ( pxTCB - > uxPriority > = pxCurrentTCB - > uxPriority ) ;
/* As we are in a critical section we can access the ready
lists even if the scheduler is suspended . */
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 . */
xYieldRequired = pdFALSE ;
vListInsertEnd ( ( xList * ) & ( xPendingReadyList ) , & ( pxTCB - > xEventListItem ) ) ;
/* 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 ( ) ;
}
}
}
taskEXIT_CRITICAL ( ) ;
}
}
# endif
/*-----------------------------------------------------------*/
/* We may have just resumed a higher priority task. */
if ( xYieldRequired )
# if ( INCLUDE_vTaskResumeFromISR == 1 )
portBASE_TYPE xTaskResumeFromISR ( xTaskHandle pxTaskToResume )
{
portBASE_TYPE xYieldRequired ;
/* Is the task we are attempting to resume actually suspended? */
if ( listIS_CONTAINED_WITHIN ( & xSuspendedTaskList , & ( pxTaskToResume - > xGenericListItem ) ) ! = pdFALSE )
{
if ( uxSchedulerSuspended = = ( unsigned portBASE_TYPE ) pdFALSE )
{
/* 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 ( ) ;
xYieldRequired = ( pxTaskToResume - > uxPriority > = pxCurrentTCB - > uxPriority ) ;
vListRemove ( & ( pxTaskToResume - > xGenericListItem ) ) ;
prvAddTaskToReadyQueue ( pxTaskToResume ) ;
}
else
{
/* We cannot access the delayed or ready lists, so will hold this
task pending until the scheduler is resumed . */
xYieldRequired = pdFALSE ;
vListInsertEnd ( ( xList * ) & ( xPendingReadyList ) , & ( pxTaskToResume - > xEventListItem ) ) ;
}
}
return xYieldRequired ;
}
# endif
@ -954,7 +985,6 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
/*-----------------------------------------------------------
* PUBLIC SCHEDULER CONTROL documented in task . h
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */