mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 21:41:59 -04:00
First version that includes the FreeRTOS-MPU implementation.
This commit is contained in:
parent
291ea26bfe
commit
cf717acaae
219
Source/tasks.c
219
Source/tasks.c
|
@ -50,15 +50,24 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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 "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "StackMacros.h"
|
#include "StackMacros.h"
|
||||||
|
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro to define the amount of stack available to the idle task.
|
* Macro to define the amount of stack available to the idle task.
|
||||||
*/
|
*/
|
||||||
#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE
|
#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,
|
* Task control block. A task control block (TCB) is allocated to each task,
|
||||||
* and stores the context of the task.
|
* and stores the context of the task.
|
||||||
|
@ -66,6 +75,11 @@
|
||||||
typedef struct tskTaskControlBlock
|
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. */
|
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 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. */
|
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. */
|
unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */
|
||||||
|
@ -98,6 +112,7 @@ typedef struct tskTaskControlBlock
|
||||||
|
|
||||||
} tskTCB;
|
} tskTCB;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some kernel aware debuggers require data to be viewed to be global, rather
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
* than file scope.
|
* than file scope.
|
||||||
|
@ -107,48 +122,47 @@ typedef struct tskTaskControlBlock
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*lint -e956 */
|
/*lint -e956 */
|
||||||
|
PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;
|
||||||
tskTCB * volatile pxCurrentTCB = NULL;
|
|
||||||
|
|
||||||
/* Lists for ready and blocked tasks. --------------------*/
|
/* Lists for ready and blocked tasks. --------------------*/
|
||||||
|
|
||||||
static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */
|
PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */
|
||||||
static xList xDelayedTaskList1; /*< Delayed tasks. */
|
PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */
|
||||||
static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
|
PRIVILEGED_DATA 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. */
|
PRIVILEGED_DATA 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. */
|
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. */
|
||||||
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 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 )
|
#if ( INCLUDE_vTaskDelete == 1 )
|
||||||
|
|
||||||
static volatile xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */
|
PRIVILEGED_DATA 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 unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||||
|
|
||||||
static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */
|
PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* File private variables. --------------------------------*/
|
/* File private variables. --------------------------------*/
|
||||||
static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0;
|
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0;
|
||||||
static volatile portTickType xTickCount = ( portTickType ) 0;
|
PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0;
|
||||||
static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
|
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
|
||||||
static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
|
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
|
||||||
static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
|
PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
|
||||||
static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;
|
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;
|
||||||
static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0;
|
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0;
|
||||||
static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
|
PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
|
||||||
static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
|
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
|
||||||
static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0;
|
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0;
|
||||||
|
|
||||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||||
|
|
||||||
static portCHAR pcStatsString[ 50 ];
|
PRIVILEGED_DATA static portCHAR pcStatsString[ 50 ] ;
|
||||||
static unsigned portLONG ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
|
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 );
|
static void prvGenerateRunTimeStatsForTasksInList( const signed portCHAR *pcWriteBuffer, xList *pxList, unsigned portLONG ulTotalRunTime ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -174,12 +188,12 @@ static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0;
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
|
||||||
#define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned portLONG ) ( sizeof( unsigned portLONG ) + sizeof( unsigned portLONG ) ) )
|
#define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned portLONG ) ( sizeof( unsigned portLONG ) + sizeof( unsigned portLONG ) ) )
|
||||||
static volatile signed portCHAR * volatile pcTraceBuffer;
|
PRIVILEGED_DATA static volatile signed portCHAR * volatile pcTraceBuffer;
|
||||||
static signed portCHAR *pcTraceBufferStart;
|
PRIVILEGED_DATA static signed portCHAR *pcTraceBufferStart;
|
||||||
static signed portCHAR *pcTraceBufferEnd;
|
PRIVILEGED_DATA static signed portCHAR *pcTraceBufferEnd;
|
||||||
static signed portBASE_TYPE xTracing = pdFALSE;
|
PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE;
|
||||||
static unsigned portBASE_TYPE uxPreviousTask = 255;
|
PRIVILEGED_DATA static unsigned portBASE_TYPE uxPreviousTask = 255;
|
||||||
static portCHAR pcStatusString[ 50 ];
|
PRIVILEGED_DATA static portCHAR pcStatusString[ 50 ];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -283,13 +297,13 @@ register tskTCB *pxTCB; \
|
||||||
* Utility to ready a TCB for a given task. Mainly just copies the parameters
|
* Utility to ready a TCB for a given task. Mainly just copies the parameters
|
||||||
* into the TCB structure.
|
* 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
|
* Utility to ready all the lists used by the scheduler. This is called
|
||||||
* automatically upon the creation of the first task.
|
* 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.
|
* 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 ) )
|
#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
|
||||||
|
|
||||||
static void prvDeleteTCB( tskTCB *pxTCB );
|
static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#endif
|
#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
|
* in the list of tasks waiting to be deleted. If so the task is cleaned up
|
||||||
* and its TCB deleted.
|
* 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
|
* Allocates memory from the heap for a TCB and associated stack. Checks the
|
||||||
* allocation was successful.
|
* 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
|
* 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 )
|
#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
|
#endif
|
||||||
|
|
||||||
|
@ -352,7 +366,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
|
||||||
*/
|
*/
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
|
#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
|
#endif
|
||||||
|
|
||||||
|
@ -365,27 +379,36 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
|
||||||
* TASK CREATION API documented in task.h
|
* TASK CREATION API documented in task.h
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask )
|
signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, 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;
|
signed portBASE_TYPE xReturn;
|
||||||
tskTCB * pxNewTCB;
|
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. */
|
checking that the allocation was successful. */
|
||||||
pxNewTCB = prvAllocateTCBAndStack( usStackDepth );
|
pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
|
||||||
|
|
||||||
if( pxNewTCB != NULL )
|
if( pxNewTCB != NULL )
|
||||||
{
|
{
|
||||||
portSTACK_TYPE *pxTopOfStack;
|
portSTACK_TYPE *pxTopOfStack;
|
||||||
|
|
||||||
/* Setup the newly allocated TCB with the initial state of the task. */
|
/* Should the task be created in privileged mode? */
|
||||||
prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority );
|
if( ( uxPriority & portPRIVILEGE_BIT ) != 0x00 )
|
||||||
|
{
|
||||||
|
xRunPrivileged = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xRunPrivileged = pdFALSE;
|
||||||
|
}
|
||||||
|
uxPriority &= ~portPRIVILEGE_BIT;
|
||||||
|
|
||||||
/* Calculate the top of stack address. This depends on whether the
|
/* Calculate the top of stack address. This depends on whether the
|
||||||
stack grows from high memory to low (as per the 80x86) or visa versa.
|
stack grows from high memory to low (as per the 80x86) or visa versa.
|
||||||
portSTACK_GROWTH is used to make the result positive or negative as
|
portSTACK_GROWTH is used to make the result positive or negative as
|
||||||
required by the port. */
|
required by the port. */
|
||||||
#if portSTACK_GROWTH < 0
|
#if( portSTACK_GROWTH < 0 )
|
||||||
{
|
{
|
||||||
pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ) - ( ( usStackDepth - 1 ) % portBYTE_ALIGNMENT );
|
pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ) - ( ( usStackDepth - 1 ) % portBYTE_ALIGNMENT );
|
||||||
}
|
}
|
||||||
|
@ -400,11 +423,23 @@ tskTCB * pxNewTCB;
|
||||||
}
|
}
|
||||||
#endif
|
#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,
|
/* 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
|
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
|
to the start of the task function. Once the stack has been initialised
|
||||||
the top of stack variable is updated. */
|
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
|
/* We are going to manipulate the task queues to add this task to a
|
||||||
ready list, so must make sure no interrupts occur. */
|
ready list, so must make sure no interrupts occur. */
|
||||||
|
@ -479,7 +514,7 @@ tskTCB * pxNewTCB;
|
||||||
then it should run now. */
|
then it should run now. */
|
||||||
if( pxCurrentTCB->uxPriority < uxPriority )
|
if( pxCurrentTCB->uxPriority < uxPriority )
|
||||||
{
|
{
|
||||||
taskYIELD();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,7 +529,7 @@ tskTCB * pxNewTCB;
|
||||||
{
|
{
|
||||||
tskTCB *pxTCB;
|
tskTCB *pxTCB;
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/* Ensure a yield is performed if the current task is being
|
/* Ensure a yield is performed if the current task is being
|
||||||
deleted. */
|
deleted. */
|
||||||
|
@ -531,14 +566,14 @@ tskTCB * pxNewTCB;
|
||||||
|
|
||||||
traceTASK_DELETE( pxTCB );
|
traceTASK_DELETE( pxTCB );
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
/* Force a reschedule if we have just deleted the current task. */
|
/* Force a reschedule if we have just deleted the current task. */
|
||||||
if( xSchedulerRunning != pdFALSE )
|
if( xSchedulerRunning != pdFALSE )
|
||||||
{
|
{
|
||||||
if( ( void * ) pxTaskToDelete == NULL )
|
if( ( void * ) pxTaskToDelete == NULL )
|
||||||
{
|
{
|
||||||
taskYIELD();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,7 +659,7 @@ tskTCB * pxNewTCB;
|
||||||
have put ourselves to sleep. */
|
have put ourselves to sleep. */
|
||||||
if( !xAlreadyYielded )
|
if( !xAlreadyYielded )
|
||||||
{
|
{
|
||||||
taskYIELD();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,7 +720,7 @@ tskTCB * pxNewTCB;
|
||||||
have put ourselves to sleep. */
|
have put ourselves to sleep. */
|
||||||
if( !xAlreadyYielded )
|
if( !xAlreadyYielded )
|
||||||
{
|
{
|
||||||
taskYIELD();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,14 +734,14 @@ tskTCB * pxNewTCB;
|
||||||
tskTCB *pxTCB;
|
tskTCB *pxTCB;
|
||||||
unsigned portBASE_TYPE uxReturn;
|
unsigned portBASE_TYPE uxReturn;
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/* If null is passed in here then we are changing the
|
/* If null is passed in here then we are changing the
|
||||||
priority of the calling function. */
|
priority of the calling function. */
|
||||||
pxTCB = prvGetTCBFromHandle( pxTask );
|
pxTCB = prvGetTCBFromHandle( pxTask );
|
||||||
uxReturn = pxTCB->uxPriority;
|
uxReturn = pxTCB->uxPriority;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
return uxReturn;
|
return uxReturn;
|
||||||
}
|
}
|
||||||
|
@ -727,7 +762,7 @@ tskTCB * pxNewTCB;
|
||||||
uxNewPriority = configMAX_PRIORITIES - 1;
|
uxNewPriority = configMAX_PRIORITIES - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
if( pxTask == pxCurrentTCB )
|
if( pxTask == pxCurrentTCB )
|
||||||
{
|
{
|
||||||
|
@ -809,11 +844,11 @@ tskTCB * pxNewTCB;
|
||||||
|
|
||||||
if( xYieldRequired == pdTRUE )
|
if( xYieldRequired == pdTRUE )
|
||||||
{
|
{
|
||||||
taskYIELD();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -825,7 +860,7 @@ tskTCB * pxNewTCB;
|
||||||
{
|
{
|
||||||
tskTCB *pxTCB;
|
tskTCB *pxTCB;
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/* Ensure a yield is performed if the current task is being
|
/* Ensure a yield is performed if the current task is being
|
||||||
suspended. */
|
suspended. */
|
||||||
|
@ -850,12 +885,12 @@ tskTCB * pxNewTCB;
|
||||||
|
|
||||||
vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
|
vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
/* We may have just suspended the current task. */
|
/* We may have just suspended the current task. */
|
||||||
if( ( void * ) pxTaskToSuspend == NULL )
|
if( ( void * ) pxTaskToSuspend == NULL )
|
||||||
{
|
{
|
||||||
taskYIELD();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -907,7 +942,7 @@ tskTCB * pxNewTCB;
|
||||||
currently executing task. */
|
currently executing task. */
|
||||||
if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
|
if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
|
if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
|
||||||
{
|
{
|
||||||
|
@ -923,11 +958,11 @@ tskTCB * pxNewTCB;
|
||||||
{
|
{
|
||||||
/* 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();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,7 +1016,7 @@ void vTaskStartScheduler( void )
|
||||||
portBASE_TYPE xReturn;
|
portBASE_TYPE xReturn;
|
||||||
|
|
||||||
/* Add the idle task at the lowest priority. */
|
/* 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 )
|
if( xReturn == pdPASS )
|
||||||
{
|
{
|
||||||
|
@ -1098,7 +1133,7 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
|
||||||
{
|
{
|
||||||
xAlreadyYielded = pdTRUE;
|
xAlreadyYielded = pdTRUE;
|
||||||
xMissedYield = pdFALSE;
|
xMissedYield = pdFALSE;
|
||||||
taskYIELD();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1124,11 +1159,11 @@ portTickType xTaskGetTickCount( void )
|
||||||
portTickType xTicks;
|
portTickType xTicks;
|
||||||
|
|
||||||
/* Critical section required if running on a 16 bit processor. */
|
/* Critical section required if running on a 16 bit processor. */
|
||||||
taskENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
xTicks = xTickCount;
|
xTicks = xTickCount;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
return xTicks;
|
return xTicks;
|
||||||
}
|
}
|
||||||
|
@ -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. */
|
/* Store the function name in the TCB. */
|
||||||
#if configMAX_TASK_NAME_LEN > 1
|
#if configMAX_TASK_NAME_LEN > 1
|
||||||
|
@ -1811,7 +1846,8 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * co
|
||||||
#endif
|
#endif
|
||||||
pxTCB->pcTaskName[ ( unsigned portSHORT ) configMAX_TASK_NAME_LEN - ( unsigned portSHORT ) 1 ] = '\0';
|
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 )
|
if( uxPriority >= configMAX_PRIORITIES )
|
||||||
{
|
{
|
||||||
uxPriority = configMAX_PRIORITIES - 1;
|
uxPriority = configMAX_PRIORITIES - 1;
|
||||||
|
@ -1852,9 +1888,39 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * co
|
||||||
pxTCB->ulRunTimeCounter = 0UL;
|
pxTCB->ulRunTimeCounter = 0UL;
|
||||||
}
|
}
|
||||||
#endif
|
#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 )
|
static void prvInitialiseTaskLists( void )
|
||||||
{
|
{
|
||||||
unsigned portBASE_TYPE uxPriority;
|
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;
|
tskTCB *pxNewTCB;
|
||||||
|
|
||||||
|
@ -1935,7 +2001,7 @@ tskTCB *pxNewTCB;
|
||||||
/* Allocate space for the stack used by the task being created.
|
/* 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
|
The base of the stack memory stored in the TCB so the task can
|
||||||
be deleted later if required. */
|
be deleted later if required. */
|
||||||
pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMalloc( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) );
|
pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer );
|
||||||
|
|
||||||
if( pxNewTCB->pxStack == NULL )
|
if( pxNewTCB->pxStack == NULL )
|
||||||
{
|
{
|
||||||
|
@ -2028,7 +2094,7 @@ tskTCB *pxNewTCB;
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
|
#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;
|
register unsigned portSHORT usCount = 0;
|
||||||
|
|
||||||
|
@ -2052,6 +2118,7 @@ tskTCB *pxNewTCB;
|
||||||
{
|
{
|
||||||
tskTCB *pxTCB;
|
tskTCB *pxTCB;
|
||||||
unsigned portCHAR *pcEndOfStack;
|
unsigned portCHAR *pcEndOfStack;
|
||||||
|
unsigned portBASE_TYPE uxReturn;
|
||||||
|
|
||||||
pxTCB = prvGetTCBFromHandle( xTask );
|
pxTCB = prvGetTCBFromHandle( xTask );
|
||||||
|
|
||||||
|
@ -2065,7 +2132,9 @@ tskTCB *pxNewTCB;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return usTaskCheckFreeStackSpace( pcEndOfStack );
|
uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace( pcEndOfStack );
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2077,7 +2146,7 @@ tskTCB *pxNewTCB;
|
||||||
{
|
{
|
||||||
/* Free up the memory allocated by the scheduler for the task. It is up to
|
/* 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. */
|
the task to free any memory allocated at the application level. */
|
||||||
vPortFree( pxTCB->pxStack );
|
vPortFreeAligned( pxTCB->pxStack );
|
||||||
vPortFree( pxTCB );
|
vPortFree( pxTCB );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2090,10 +2159,14 @@ tskTCB *pxNewTCB;
|
||||||
|
|
||||||
xTaskHandle xTaskGetCurrentTaskHandle( void )
|
xTaskHandle xTaskGetCurrentTaskHandle( void )
|
||||||
{
|
{
|
||||||
|
xTaskHandle xReturn;
|
||||||
|
|
||||||
/* A critical section is not required as this is not called from
|
/* 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
|
an interrupt and the current TCB will always be the same for any
|
||||||
individual execution thread. */
|
individual execution thread. */
|
||||||
return pxCurrentTCB;
|
xReturn = pxCurrentTCB;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue