mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-21 22:11:57 -04:00
First version that includes the FreeRTOS-MPU implementation.
This commit is contained in:
parent
291ea26bfe
commit
cf717acaae
247
Source/tasks.c
247
Source/tasks.c
|
@ -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 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;
|
||||
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 80x86) 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 )
|
||||
{
|
||||
taskYIELD();
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +529,7 @@ tskTCB * pxNewTCB;
|
|||
{
|
||||
tskTCB *pxTCB;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
/* Ensure a yield is performed if the current task is being
|
||||
deleted. */
|
||||
|
@ -531,14 +566,14 @@ tskTCB * pxNewTCB;
|
|||
|
||||
traceTASK_DELETE( pxTCB );
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
portEXIT_CRITICAL();
|
||||
|
||||
/* Force a reschedule if we have just deleted the current task. */
|
||||
if( xSchedulerRunning != pdFALSE )
|
||||
{
|
||||
if( ( void * ) pxTaskToDelete == NULL )
|
||||
{
|
||||
taskYIELD();
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -624,7 +659,7 @@ tskTCB * pxNewTCB;
|
|||
have put ourselves to sleep. */
|
||||
if( !xAlreadyYielded )
|
||||
{
|
||||
taskYIELD();
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -685,7 +720,7 @@ tskTCB * pxNewTCB;
|
|||
have put ourselves to sleep. */
|
||||
if( !xAlreadyYielded )
|
||||
{
|
||||
taskYIELD();
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -699,14 +734,14 @@ tskTCB * pxNewTCB;
|
|||
tskTCB *pxTCB;
|
||||
unsigned portBASE_TYPE uxReturn;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
/* If null is passed in here then we are changing the
|
||||
priority of the calling function. */
|
||||
pxTCB = prvGetTCBFromHandle( pxTask );
|
||||
uxReturn = pxTCB->uxPriority;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
portEXIT_CRITICAL();
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
|
@ -727,7 +762,7 @@ tskTCB * pxNewTCB;
|
|||
uxNewPriority = configMAX_PRIORITIES - 1;
|
||||
}
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
if( pxTask == pxCurrentTCB )
|
||||
{
|
||||
|
@ -809,11 +844,11 @@ tskTCB * pxNewTCB;
|
|||
|
||||
if( xYieldRequired == pdTRUE )
|
||||
{
|
||||
taskYIELD();
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
portEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -825,7 +860,7 @@ tskTCB * pxNewTCB;
|
|||
{
|
||||
tskTCB *pxTCB;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
/* Ensure a yield is performed if the current task is being
|
||||
suspended. */
|
||||
|
@ -850,12 +885,12 @@ tskTCB * pxNewTCB;
|
|||
|
||||
vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
portEXIT_CRITICAL();
|
||||
|
||||
/* We may have just suspended the current task. */
|
||||
if( ( void * ) pxTaskToSuspend == NULL )
|
||||
{
|
||||
taskYIELD();
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -907,7 +942,7 @@ tskTCB * pxNewTCB;
|
|||
currently executing task. */
|
||||
if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
portENTER_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. */
|
||||
taskYIELD();
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
portEXIT_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;
|
||||
taskYIELD();
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1124,11 +1159,11 @@ portTickType xTaskGetTickCount( void )
|
|||
portTickType xTicks;
|
||||
|
||||
/* Critical section required if running on a 16 bit processor. */
|
||||
taskENTER_CRITICAL();
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
xTicks = xTickCount;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
portEXIT_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 * ) pvPortMallocAligned( ( ( ( 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 );
|
||||
vPortFreeAligned( 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
|
||||
|
|
Loading…
Reference in a new issue