@ -24,10 +24,10 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Looking for a quick start ? Then check out the FreeRTOS eBook ! *
* See http : //www.FreeRTOS.org/Documentation for details *
* *
* *
* Looking for a quick start ? Then check out the FreeRTOS eBook ! *
* See http : //www.FreeRTOS.org/Documentation for details *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1 tab = = 4 spaces !
@ -50,15 +50,24 @@
# include <stdlib.h>
# include <string.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers . That should only be done when
task . h is included from an application file . */
# define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
# include "FreeRTOS.h"
# include "task.h"
# include "StackMacros.h"
# undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/*
* Macro to define the amount of stack available to the idle task .
*/
# define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE
# define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0 )
/*
* Task control block . A task control block ( TCB ) is allocated to each task ,
* and stores the context of the task .
@ -66,6 +75,11 @@
typedef struct tskTaskControlBlock
{
volatile portSTACK_TYPE * pxTopOfStack ; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */
# if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings ; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */
# endif
xListItem xGenericListItem ; /*< List item used to place the TCB in ready and blocked queues. */
xListItem xEventListItem ; /*< List item used to place the TCB in event lists. */
unsigned portBASE_TYPE uxPriority ; /*< The priority of the task where 0 is the lowest priority. */
@ -93,11 +107,12 @@ typedef struct tskTaskControlBlock
# endif
# if ( configGENERATE_RUN_TIME_STATS == 1 )
unsigned portLONG ulRunTimeCounter ; /*< Used for calculating how much CPU time each task is utilising. */
unsigned portLONG ulRunTimeCounter ; /*< Used for calculating how much CPU time each task is utilising. */
# endif
} tskTCB ;
/*
* Some kernel aware debuggers require data to be viewed to be global , rather
* than file scope .
@ -107,48 +122,47 @@ typedef struct tskTaskControlBlock
# endif
/*lint -e956 */
tskTCB * volatile pxCurrentTCB = NULL ;
PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL ;
/* Lists for ready and blocked tasks. --------------------*/
static xList pxReadyTasksLists [ configMAX_PRIORITIES ] ; /*< Prioritised ready tasks. */
static xList xDelayedTaskList1 ; /*< Delayed tasks. */
static xList xDelayedTaskList2 ; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */
static xList * volatile pxOverflowDelayedTaskList ; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
static xList xPendingReadyList ; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */
PRIVILEGED_DATA static xList pxReadyTasksLists [ configMAX_PRIORITIES ] ; /*< Prioritised ready tasks. */
PRIVILEGED_DATA static xList xDelayedTaskList1 ; /*< Delayed tasks. */
PRIVILEGED_DATA static xList xDelayedTaskList2 ; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */
PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList ; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
PRIVILEGED_DATA static xList xPendingReadyList ; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */
# if ( INCLUDE_vTaskDelete == 1 )
static volatile xList xTasksWaitingTermination ; /*< Tasks that have been deleted - but the their memory not yet freed. */
static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0 ;
PRIVILEGED_DATA static volatile xList xTasksWaitingTermination ; /*< Tasks that have been deleted - but the their memory not yet freed. */
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0 ;
# endif
# if ( INCLUDE_vTaskSuspend == 1 )
static xList xSuspendedTaskList ; /*< Tasks that are currently suspended. */
PRIVILEGED_DATA static xList xSuspendedTaskList ; /*< Tasks that are currently suspended. */
# endif
/* File private variables. --------------------------------*/
static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0 ;
static volatile portTickType xTickCount = ( portTickType ) 0 ;
static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY ;
static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY ;
static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE ;
static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE ;
static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0 ;
static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE ;
static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0 ;
static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0 ;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0 ;
PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0 ;
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY ;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY ;
PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE ;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE ;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0 ;
PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE ;
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0 ;
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0 ;
# if ( configGENERATE_RUN_TIME_STATS == 1 )
static portCHAR pcStatsString [ 50 ] ;
static unsigned portLONG ulTaskSwitchedInTime = 0UL ; /*< Holds the value of a timer/counter the last time a task was switched in. */
static void prvGenerateRunTimeStatsForTasksInList ( const signed portCHAR * pcWriteBuffer , xList * pxList , unsigned portLONG ulTotalRunTime ) ;
PRIVILEGED_DATA static portCHAR pcStatsString [ 50 ] ;
PRIVILEGED_DATA static unsigned portLONG ulTaskSwitchedInTime = 0UL ; /*< Holds the value of a timer/counter the last time a task was switched in. */
static void prvGenerateRunTimeStatsForTasksInList ( const signed portCHAR * pcWriteBuffer , xList * pxList , unsigned portLONG ulTotalRunTime ) PRIVILEGED_FUNCTION ;
# endif
@ -174,12 +188,12 @@ static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0;
# if ( configUSE_TRACE_FACILITY == 1 )
# define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned portLONG ) ( sizeof( unsigned portLONG ) + sizeof( unsigned portLONG ) ) )
static volatile signed portCHAR * volatile pcTraceBuffer ;
static signed portCHAR * pcTraceBufferStart ;
static signed portCHAR * pcTraceBufferEnd ;
static signed portBASE_TYPE xTracing = pdFALSE ;
static unsigned portBASE_TYPE uxPreviousTask = 255 ;
static portCHAR pcStatusString [ 50 ] ;
PRIVILEGED_DATA static volatile signed portCHAR * volatile pcTraceBuffer ;
PRIVILEGED_DATA static signed portCHAR * pcTraceBufferStart ;
PRIVILEGED_DATA static signed portCHAR * pcTraceBufferEnd ;
PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE ;
PRIVILEGED_DATA static unsigned portBASE_TYPE uxPreviousTask = 255 ;
PRIVILEGED_DATA static portCHAR pcStatusString [ 50 ] ;
# endif
@ -283,13 +297,13 @@ register tskTCB *pxTCB; \
* Utility to ready a TCB for a given task . Mainly just copies the parameters
* into the TCB structure .
*/
static void prvInitialiseTCBVariables ( tskTCB * pxTCB , const signed portCHAR * const pcName , unsigned portBASE_TYPE uxPriority ) ;
static void prvInitialiseTCBVariables ( tskTCB * pxTCB , const signed portCHAR * const pcName , unsigned portBASE_TYPE uxPriority , const xMemoryRegion * const xRegions , unsigned portSHORT usStackDepth ) PRIVILEGED_FUNCTION ;
/*
* Utility to ready all the lists used by the scheduler . This is called
* automatically upon the creation of the first task .
*/
static void prvInitialiseTaskLists ( void ) ;
static void prvInitialiseTaskLists ( void ) PRIVILEGED_FUNCTION ;
/*
* The idle task , which as all tasks is implemented as a never ending loop .
@ -313,7 +327,7 @@ static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
*/
# if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
static void prvDeleteTCB ( tskTCB * pxTCB ) ;
static void prvDeleteTCB ( tskTCB * pxTCB ) PRIVILEGED_FUNCTION ;
# endif
@ -322,13 +336,13 @@ static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
* in the list of tasks waiting to be deleted . If so the task is cleaned up
* and its TCB deleted .
*/
static void prvCheckTasksWaitingTermination ( void ) ;
static void prvCheckTasksWaitingTermination ( void ) PRIVILEGED_FUNCTION ;
/*
* Allocates memory from the heap for a TCB and associated stack . Checks the
* allocation was successful .
*/
static tskTCB * prvAllocateTCBAndStack ( unsigned portSHORT usStackDepth ) ;
static tskTCB * prvAllocateTCBAndStack ( unsigned portSHORT usStackDepth , portSTACK_TYPE * puxStackBuffer ) PRIVILEGED_FUNCTION ;
/*
* Called from vTaskList . vListTasks details all the tasks currently under
@ -341,7 +355,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
*/
# if ( configUSE_TRACE_FACILITY == 1 )
static void prvListTaskWithinSingleList ( const signed portCHAR * pcWriteBuffer , xList * pxList , signed portCHAR cStatus ) ;
static void prvListTaskWithinSingleList ( const signed portCHAR * pcWriteBuffer , xList * pxList , signed portCHAR cStatus ) PRIVILEGED_FUNCTION ;
# endif
@ -352,7 +366,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
*/
# if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
unsigned portSHORT usTaskCheckFreeStackSpace ( const unsigned portCHAR * pucStackByte ) ;
static unsigned portSHORT usTaskCheckFreeStackSpace ( const unsigned portCHAR * pucStackByte ) PRIVILEGED_FUNCTION ;
# endif
@ -365,27 +379,36 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
* TASK CREATION API documented in task . h
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
signed portBASE_TYPE xTask Create( pdTASK_CODE pv TaskCode, const signed portCHAR * const pcName , unsigned portSHORT usStackDepth , void * pvParameters , unsigned portBASE_TYPE uxPriority , xTaskHandle * pxCreatedTask )
signed portBASE_TYPE xTask GenericCreate( pdTASK_CODE px TaskCode, const signed portCHAR * const pcName , unsigned portSHORT usStackDepth , void * pvParameters , unsigned portBASE_TYPE uxPriority , xTaskHandle * pxCreatedTask , portSTACK_TYPE * puxStackBuffer , const xMemoryRegion * const xRegions )
{
signed portBASE_TYPE xReturn ;
tskTCB * pxNewTCB ;
portBASE_TYPE xRunPrivileged ;
/* Allocate the memory required by the TCB and stack for the new task .
/* Allocate the memory required by the TCB and stack for the new task ,
checking that the allocation was successful . */
pxNewTCB = prvAllocateTCBAndStack ( usStackDepth ) ;
pxNewTCB = prvAllocateTCBAndStack ( usStackDepth , puxStackBuffer ) ;
if ( pxNewTCB ! = NULL )
{
portSTACK_TYPE * pxTopOfStack ;
/* Setup the newly allocated TCB with the initial state of the task. */
prvInitialiseTCBVariables ( pxNewTCB , pcName , uxPriority ) ;
/* Should the task be created in privileged mode? */
if ( ( uxPriority & portPRIVILEGE_BIT ) ! = 0x00 )
{
xRunPrivileged = pdTRUE ;
}
else
{
xRunPrivileged = pdFALSE ;
}
uxPriority & = ~ portPRIVILEGE_BIT ;
/* Calculate the top of stack address. This depends on whether the
stack grows from high memory to low ( as per the 80 x86 ) or visa versa .
portSTACK_GROWTH is used to make the result positive or negative as
required by the port . */
# if portSTACK_GROWTH < 0
# if ( portSTACK_GROWTH < 0 )
{
pxTopOfStack = pxNewTCB - > pxStack + ( usStackDepth - 1 ) - ( ( usStackDepth - 1 ) % portBYTE_ALIGNMENT ) ;
}
@ -400,11 +423,23 @@ tskTCB * pxNewTCB;
}
# endif
/* Setup the newly allocated TCB with the initial state of the task. */
prvInitialiseTCBVariables ( pxNewTCB , pcName , uxPriority , xRegions , usStackDepth ) ;
/* Initialize the TCB stack to look as if the task was already running,
but had been interrupted by the scheduler . The return address is set
to the start of the task function . Once the stack has been initialised
the top of stack variable is updated . */
pxNewTCB - > pxTopOfStack = pxPortInitialiseStack ( pxTopOfStack , pvTaskCode , pvParameters ) ;
# if( portUSING_MPU_WRAPPERS == 1 )
{
pxNewTCB - > pxTopOfStack = pxPortInitialiseStack ( pxTopOfStack , pxTaskCode , pvParameters , xRunPrivileged ) ;
}
# else
{
pxNewTCB - > pxTopOfStack = pxPortInitialiseStack ( pxTopOfStack , pxTaskCode , pvParameters ) ;
( void ) xRunPrivileged ;
}
# endif
/* We are going to manipulate the task queues to add this task to a
ready list , so must make sure no interrupts occur . */
@ -479,7 +514,7 @@ tskTCB * pxNewTCB;
then it should run now . */
if ( pxCurrentTCB - > uxPriority < uxPriority )
{
task YIELD( ) ;
por tYIELD_WITHIN_API ( ) ;
}
}
}
@ -494,7 +529,7 @@ tskTCB * pxNewTCB;
{
tskTCB * pxTCB ;
task ENTER_CRITICAL( ) ;
por tENTER_CRITICAL( ) ;
{
/* Ensure a yield is performed if the current task is being
deleted . */
@ -531,14 +566,14 @@ tskTCB * pxNewTCB;
traceTASK_DELETE ( pxTCB ) ;
}
task EXIT_CRITICAL( ) ;
por tEXIT_CRITICAL( ) ;
/* Force a reschedule if we have just deleted the current task. */
if ( xSchedulerRunning ! = pdFALSE )
{
if ( ( void * ) pxTaskToDelete = = NULL )
{
task YIELD( ) ;
por tYIELD_WITHIN_API ( ) ;
}
}
}
@ -624,7 +659,7 @@ tskTCB * pxNewTCB;
have put ourselves to sleep . */
if ( ! xAlreadyYielded )
{
task YIELD( ) ;
por tYIELD_WITHIN_API ( ) ;
}
}
@ -685,7 +720,7 @@ tskTCB * pxNewTCB;
have put ourselves to sleep . */
if ( ! xAlreadyYielded )
{
task YIELD( ) ;
por tYIELD_WITHIN_API ( ) ;
}
}
@ -699,14 +734,14 @@ tskTCB * pxNewTCB;
tskTCB * pxTCB ;
unsigned portBASE_TYPE uxReturn ;
task ENTER_CRITICAL( ) ;
por tENTER_CRITICAL( ) ;
{
/* If null is passed in here then we are changing the
priority of the calling function . */
pxTCB = prvGetTCBFromHandle ( pxTask ) ;
uxReturn = pxTCB - > uxPriority ;
}
task EXIT_CRITICAL( ) ;
por tEXIT_CRITICAL( ) ;
return uxReturn ;
}
@ -727,7 +762,7 @@ tskTCB * pxNewTCB;
uxNewPriority = configMAX_PRIORITIES - 1 ;
}
task ENTER_CRITICAL( ) ;
por tENTER_CRITICAL( ) ;
{
if ( pxTask = = pxCurrentTCB )
{
@ -809,11 +844,11 @@ tskTCB * pxNewTCB;
if ( xYieldRequired = = pdTRUE )
{
task YIELD( ) ;
por tYIELD_WITHIN_API ( ) ;
}
}
}
task EXIT_CRITICAL( ) ;
por tEXIT_CRITICAL( ) ;
}
# endif
@ -825,7 +860,7 @@ tskTCB * pxNewTCB;
{
tskTCB * pxTCB ;
task ENTER_CRITICAL( ) ;
por tENTER_CRITICAL( ) ;
{
/* Ensure a yield is performed if the current task is being
suspended . */
@ -850,12 +885,12 @@ tskTCB * pxNewTCB;
vListInsertEnd ( ( xList * ) & xSuspendedTaskList , & ( pxTCB - > xGenericListItem ) ) ;
}
task EXIT_CRITICAL( ) ;
por tEXIT_CRITICAL( ) ;
/* We may have just suspended the current task. */
if ( ( void * ) pxTaskToSuspend = = NULL )
{
task YIELD( ) ;
por tYIELD_WITHIN_API ( ) ;
}
}
@ -907,7 +942,7 @@ tskTCB * pxNewTCB;
currently executing task . */
if ( ( pxTCB ! = NULL ) & & ( pxTCB ! = pxCurrentTCB ) )
{
task ENTER_CRITICAL( ) ;
por tENTER_CRITICAL( ) ;
{
if ( xTaskIsTaskSuspended ( pxTCB ) = = pdTRUE )
{
@ -923,11 +958,11 @@ tskTCB * pxNewTCB;
{
/* This yield may not cause the task just resumed to run, but
will leave the lists in the correct state for the next yield . */
task YIELD( ) ;
por tYIELD_WITHIN_API ( ) ;
}
}
}
task EXIT_CRITICAL( ) ;
por tEXIT_CRITICAL( ) ;
}
}
@ -981,7 +1016,7 @@ void vTaskStartScheduler( void )
portBASE_TYPE xReturn ;
/* Add the idle task at the lowest priority. */
xReturn = xTaskCreate ( prvIdleTask , ( signed portCHAR * ) " IDLE " , tskIDLE_STACK_SIZE , ( void * ) NULL , tskIDLE_PRIORITY , ( xTaskHandle * ) NULL ) ;
xReturn = xTaskCreate ( prvIdleTask , ( signed portCHAR * ) " IDLE " , tskIDLE_STACK_SIZE , ( void * ) NULL , ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ) , ( xTaskHandle * ) NULL ) ;
if ( xReturn = = pdPASS )
{
@ -1087,7 +1122,7 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
/* As we have processed some ticks it is appropriate to yield
to ensure the highest priority task that is ready to run is
the task actually running . */
# if configUSE_PREEMPTION == 1
# if configUSE_PREEMPTION == 1
{
xYieldRequired = pdTRUE ;
}
@ -1098,7 +1133,7 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
{
xAlreadyYielded = pdTRUE ;
xMissedYield = pdFALSE ;
task YIELD( ) ;
por tYIELD_WITHIN_API ( ) ;
}
}
}
@ -1124,11 +1159,11 @@ portTickType xTaskGetTickCount( void )
portTickType xTicks ;
/* Critical section required if running on a 16 bit processor. */
task ENTER_CRITICAL( ) ;
por tENTER_CRITICAL( ) ;
{
xTicks = xTickCount ;
}
task EXIT_CRITICAL( ) ;
por tEXIT_CRITICAL( ) ;
return xTicks ;
}
@ -1151,7 +1186,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
/* This is a VERY costly function that should be used for debug only.
It leaves interrupts disabled for a LONG time . */
vTaskSuspendAll ( ) ;
vTaskSuspendAll ( ) ;
{
/* Run through all the lists that could potentially contain a TCB and
report the task name , state and stack high water mark . */
@ -1199,7 +1234,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
}
# endif
}
xTaskResumeAll ( ) ;
xTaskResumeAll ( ) ;
}
# endif
@ -1215,7 +1250,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
/* This is a VERY costly function that should be used for debug only.
It leaves interrupts disabled for a LONG time . */
vTaskSuspendAll ( ) ;
vTaskSuspendAll ( ) ;
{
/* Run through all the lists that could potentially contain a TCB,
generating a table of run timer percentages in the provided
@ -1264,7 +1299,7 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
}
# endif
}
xTaskResumeAll ( ) ;
xTaskResumeAll ( ) ;
}
# endif
@ -1330,7 +1365,7 @@ void vTaskIncrementTick( void )
pxTemp = pxDelayedTaskList ;
pxDelayedTaskList = pxOverflowDelayedTaskList ;
pxOverflowDelayedTaskList = pxTemp ;
xNumOfOverflows + + ;
xNumOfOverflows + + ;
}
/* See if this tick has made a timeout expire. */
@ -1671,8 +1706,8 @@ portBASE_TYPE xReturn;
void vTaskSetTimeOutState ( xTimeOutType * const pxTimeOut )
{
pxTimeOut - > xOverflowCount = xNumOfOverflows ;
pxTimeOut - > xTimeOnEntering = xTickCount ;
pxTimeOut - > xOverflowCount = xNumOfOverflows ;
pxTimeOut - > xTimeOnEntering = xTickCount ;
}
/*-----------------------------------------------------------*/
@ -1715,7 +1750,7 @@ portBASE_TYPE xReturn;
}
portEXIT_CRITICAL ( ) ;
return xReturn ;
return xReturn ;
}
/*-----------------------------------------------------------*/
@ -1800,7 +1835,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
static void prvInitialiseTCBVariables ( tskTCB * pxTCB , const signed portCHAR * const pcName , unsigned portBASE_TYPE uxPriority )
static void prvInitialiseTCBVariables ( tskTCB * pxTCB , const signed portCHAR * const pcName , unsigned portBASE_TYPE uxPriority , const xMemoryRegion * const xRegions , unsigned portSHORT usStackDepth )
{
/* Store the function name in the TCB. */
# if configMAX_TASK_NAME_LEN > 1
@ -1811,7 +1846,8 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * co
# endif
pxTCB - > pcTaskName [ ( unsigned portSHORT ) configMAX_TASK_NAME_LEN - ( unsigned portSHORT ) 1 ] = ' \0 ' ;
/* This is used as an array index so must ensure it's not too large. */
/* This is used as an array index so must ensure it's not too large. First
remove the privilege bit if one is present . */
if ( uxPriority > = configMAX_PRIORITIES )
{
uxPriority = configMAX_PRIORITIES - 1 ;
@ -1852,9 +1888,39 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * co
pxTCB - > ulRunTimeCounter = 0UL ;
}
# endif
# if ( portUSING_MPU_WRAPPERS == 1 )
{
vPortStoreTaskMPUSettings ( & ( pxTCB - > xMPUSettings ) , xRegions , pxTCB - > pxStack , usStackDepth ) ;
}
# else
{
( void ) xRegions ;
( void ) usStackDepth ;
}
# endif
}
/*-----------------------------------------------------------*/
# if ( portUSING_MPU_WRAPPERS == 1 )
void vTaskAllocateMPURegions ( xTaskHandle xTaskToModify , const xMemoryRegion * const xRegions )
{
tskTCB * pxTCB ;
if ( xTaskToModify = = pxCurrentTCB )
{
xTaskToModify = NULL ;
}
/* If null is passed in here then we are deleting ourselves. */
pxTCB = prvGetTCBFromHandle ( xTaskToModify ) ;
vPortStoreTaskMPUSettings ( & ( pxTCB - > xMPUSettings ) , xRegions , NULL , 0 ) ;
}
/*-----------------------------------------------------------*/
# endif
static void prvInitialiseTaskLists ( void )
{
unsigned portBASE_TYPE uxPriority ;
@ -1922,7 +1988,7 @@ static void prvCheckTasksWaitingTermination( void )
}
/*-----------------------------------------------------------*/
static tskTCB * prvAllocateTCBAndStack ( unsigned portSHORT usStackDepth )
static tskTCB * prvAllocateTCBAndStack ( unsigned portSHORT usStackDepth , portSTACK_TYPE * puxStackBuffer )
{
tskTCB * pxNewTCB ;
@ -1935,7 +2001,7 @@ tskTCB *pxNewTCB;
/* Allocate space for the stack used by the task being created.
The base of the stack memory stored in the TCB so the task can
be deleted later if required . */
pxNewTCB - > pxStack = ( portSTACK_TYPE * ) pvPortMalloc ( ( ( size_t ) usStackDepth ) * sizeof ( portSTACK_TYPE ) ) ;
pxNewTCB - > pxStack = ( portSTACK_TYPE * ) pvPortMalloc Aligned ( ( ( ( size_t ) usStackDepth ) * sizeof ( portSTACK_TYPE ) ) , puxStackBuffer ) ;
if ( pxNewTCB - > pxStack = = NULL )
{
@ -2028,7 +2094,7 @@ tskTCB *pxNewTCB;
# if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
unsigned portSHORT usTaskCheckFreeStackSpace ( const unsigned portCHAR * pucStackByte )
static unsigned portSHORT usTaskCheckFreeStackSpace ( const unsigned portCHAR * pucStackByte )
{
register unsigned portSHORT usCount = 0 ;
@ -2052,6 +2118,7 @@ tskTCB *pxNewTCB;
{
tskTCB * pxTCB ;
unsigned portCHAR * pcEndOfStack ;
unsigned portBASE_TYPE uxReturn ;
pxTCB = prvGetTCBFromHandle ( xTask ) ;
@ -2065,7 +2132,9 @@ tskTCB *pxNewTCB;
}
# endif
return usTaskCheckFreeStackSpace ( pcEndOfStack ) ;
uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace ( pcEndOfStack ) ;
return uxReturn ;
}
# endif
@ -2077,7 +2146,7 @@ tskTCB *pxNewTCB;
{
/* Free up the memory allocated by the scheduler for the task. It is up to
the task to free any memory allocated at the application level . */
vPortFree ( pxTCB - > pxStack ) ;
vPortFree Aligned ( pxTCB - > pxStack ) ;
vPortFree ( pxTCB ) ;
}
@ -2090,10 +2159,14 @@ tskTCB *pxNewTCB;
xTaskHandle xTaskGetCurrentTaskHandle ( void )
{
xTaskHandle xReturn ;
/* A critical section is not required as this is not called from
an interrupt and the current TCB will always be the same for any
individual execution thread . */
return pxCurrentTCB ;
xReturn = pxCurrentTCB ;
return xReturn ;
}
# endif