mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-11 13:54:16 -04:00
Updates to support FreeRTOS MPU in FreeRTOS V9.0.0 - including a GCC project that runs in the Keil simulator to allow development and testing.
This commit is contained in:
parent
255145bde1
commit
057b38ad23
16 changed files with 5877 additions and 44 deletions
|
@ -784,10 +784,6 @@ extern "C" {
|
|||
#endif /* INCLUDE_vTaskSuspend */
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION != 1 ) )
|
||||
#error configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h when the MPU is used.
|
||||
#endif
|
||||
|
||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) )
|
||||
#error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1.
|
||||
#endif
|
||||
|
|
|
@ -79,7 +79,8 @@ only for ports that are using the MPU. */
|
|||
those files. */
|
||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#define xTaskGenericCreate MPU_xTaskGenericCreate
|
||||
#define xTaskCreate MPU_xTaskCreate
|
||||
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
|
||||
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
||||
#define vTaskDelete MPU_vTaskDelete
|
||||
#define vTaskDelayUntil MPU_vTaskDelayUntil
|
||||
|
|
|
@ -357,7 +357,12 @@ is used in assert() statements. */
|
|||
* \ingroup Tasks
|
||||
*/
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint16_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -468,7 +473,13 @@ is used in assert() statements. */
|
|||
* \ingroup Tasks
|
||||
*/
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/**
|
||||
|
@ -538,7 +549,9 @@ TaskHandle_t xHandle;
|
|||
* \defgroup xTaskCreateRestricted xTaskCreateRestricted
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ( NULL ), ((x)->xRegions) )
|
||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
|
|
@ -266,7 +266,11 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
|||
* @endverbatim
|
||||
*/
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -392,7 +396,12 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
|||
* @endverbatim
|
||||
*/
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/**
|
||||
|
|
|
@ -71,8 +71,6 @@
|
|||
* Implementation of functions defined in portable.h for the ARM CM3 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#error This port is not supported in this V9.0.0 pre-release revision, but will be supported in the final release. For now use V8.2.3 instead.
|
||||
|
||||
/* 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. */
|
||||
|
@ -126,6 +124,10 @@ task.h is included from an application file. */
|
|||
/* Set the privilege level to user mode if xRunningPrivileged is false. */
|
||||
#define portRESET_PRIVILEGE( xRunningPrivileged ) if( xRunningPrivileged != pdTRUE ) __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0" :::"r0" )
|
||||
|
||||
/* For strict compliance with the Cortex-M spec the task start address should
|
||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. Note this is not saved as part of the task context as context
|
||||
switches can only occur when uxCriticalNesting is zero. */
|
||||
|
@ -176,7 +178,8 @@ static void prvSVCHandler( uint32_t *pulRegisters ) __attribute__(( noinline ))
|
|||
/*
|
||||
* Prototypes for all the MPU wrappers.
|
||||
*/
|
||||
BaseType_t MPU_xTaskGenericCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask, StackType_t *puxStackBuffer, const MemoryRegion_t * const xRegions );
|
||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask );
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask );
|
||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions );
|
||||
void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete );
|
||||
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement );
|
||||
|
@ -234,7 +237,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxCode; /* PC */
|
||||
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0; /* LR */
|
||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||
|
@ -677,12 +680,23 @@ uint32_t ul;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xTaskGenericCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask, StackType_t *puxStackBuffer, const MemoryRegion_t * const xRegions )
|
||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = prvRaisePrivilege();
|
||||
|
||||
xReturn = xTaskGenericCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, puxStackBuffer, xRegions );
|
||||
xReturn = xTaskCreateRestricted( pxTaskDefinition, pxCreatedTask );
|
||||
portRESET_PRIVILEGE( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = prvRaisePrivilege();
|
||||
|
||||
xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask );
|
||||
portRESET_PRIVILEGE( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
|
|
|
@ -262,6 +262,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
{
|
||||
xThreadState *pxThreadState = NULL;
|
||||
int8_t *pcTopOfStack = ( int8_t * ) pxTopOfStack;
|
||||
const SIZE_T xStackSize = 1024; /* Set the size to a small number which will get rounded up to the minimum possible. */
|
||||
|
||||
#ifdef portSOAK_TEST
|
||||
{
|
||||
|
@ -282,8 +283,8 @@ int8_t *pcTopOfStack = ( int8_t * ) pxTopOfStack;
|
|||
pxThreadState = ( xThreadState * ) ( pcTopOfStack - sizeof( xThreadState ) );
|
||||
|
||||
/* Create the thread itself. */
|
||||
pxThreadState->pvThread = CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE ) pxCode, pvParameters, CREATE_SUSPENDED, NULL );
|
||||
configASSERT( pxThreadState->pvThread );
|
||||
pxThreadState->pvThread = CreateThread( NULL, xStackSize, ( LPTHREAD_START_ROUTINE ) pxCode, pvParameters, CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, NULL );
|
||||
configASSERT( pxThreadState->pvThread ); /* See comment where TerminateThread() is called. */
|
||||
SetThreadAffinityMask( pxThreadState->pvThread, 0x01 );
|
||||
SetThreadPriorityBoost( pxThreadState->pvThread, TRUE );
|
||||
SetThreadPriority( pxThreadState->pvThread, portTASK_THREAD_PRIORITY );
|
||||
|
@ -490,6 +491,10 @@ uint32_t ulErrorCode;
|
|||
{
|
||||
WaitForSingleObject( pvInterruptEventMutex, INFINITE );
|
||||
|
||||
/* !!! This is not a nice way to terminate a thread, and will eventually
|
||||
result in resources being depleted if tasks frequently delete other
|
||||
tasks (rather than deleting themselves) as the task stacks will not be
|
||||
freed. */
|
||||
ulErrorCode = TerminateThread( pxThreadState->pvThread, 0 );
|
||||
configASSERT( ulErrorCode );
|
||||
|
||||
|
@ -532,6 +537,10 @@ uint32_t ulErrorCode;
|
|||
ulErrorCode = CloseHandle( pvThread );
|
||||
configASSERT( ulErrorCode );
|
||||
|
||||
/* This is called from a critical section, which must be exited before the
|
||||
thread stops. */
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
ExitThread( 0 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -117,6 +117,26 @@ functions but without including stdio.h here. */
|
|||
*/
|
||||
#define tskSTACK_FILL_BYTE ( 0xa5U )
|
||||
|
||||
/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
|
||||
dynamically allocated RAM, in which case when any task is deleted it is known
|
||||
that both the task's stack and TCB need to be freed. Sometimes the
|
||||
FreeRTOSConfig.h settings only allow a task to be created using statically
|
||||
allocated RAM, in which case when any task is deleted it is known that neither
|
||||
the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h
|
||||
settings allow a task to be created using either statically or dynamically
|
||||
allocated RAM, in which case a member of the TCB is used to record whether the
|
||||
stack and/or TCB were allocated statically or dynamically, so when a task is
|
||||
deleted the RAM that was allocated dynamically is freed again and no attempt is
|
||||
made to free the RAM that was allocated statically.
|
||||
tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a
|
||||
task to be created using either statically or dynamically allocated RAM. Note
|
||||
that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with
|
||||
a statically allocated stack and a dynamically allocated TCB. */
|
||||
#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) || ( portUSING_MPU_WRAPPERS == 1 ) )
|
||||
#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 )
|
||||
#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 )
|
||||
#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 )
|
||||
|
||||
/*
|
||||
* Macros used by vListTask to indicate which state a task is in.
|
||||
*/
|
||||
|
@ -330,8 +350,10 @@ typedef struct tskTaskControlBlock
|
|||
volatile uint8_t ucNotifyState;
|
||||
#endif
|
||||
|
||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucStaticallyAllocated; /* Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */
|
||||
/* See the comments above the definition of
|
||||
tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */
|
||||
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
|
||||
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */
|
||||
#endif
|
||||
|
||||
#if( INCLUDE_xTaskAbortDelay == 1 )
|
||||
|
@ -542,7 +564,14 @@ static void prvResetNextTaskUnblockTime( void );
|
|||
* Called after a Task_t structure has been allocated either statically or
|
||||
* dynamically to fill in the structure's members.
|
||||
*/
|
||||
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
TCB_t *pxNewTCB,
|
||||
const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
|
||||
/*
|
||||
* Called after a new task has been created and initialised to place the task
|
||||
|
@ -554,7 +583,13 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
TCB_t *pxNewTCB;
|
||||
TaskHandle_t xReturn;
|
||||
|
@ -569,15 +604,15 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer;
|
||||
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
task was created statically in case the task is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = pdTRUE;
|
||||
pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB );
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
}
|
||||
else
|
||||
|
@ -591,9 +626,59 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
#endif /* SUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||
|
||||
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask )
|
||||
{
|
||||
TCB_t *pxNewTCB;
|
||||
BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||
|
||||
configASSERT( pxTaskDefinition->puxStackBuffer );
|
||||
|
||||
if( pxTaskDefinition->puxStackBuffer != NULL )
|
||||
{
|
||||
/* Allocate space for the TCB. Where the memory comes from depends
|
||||
on the implementation of the port malloc function and whether or
|
||||
not static allocation is being used. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Store the stack location in the TCB. */
|
||||
pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer;
|
||||
|
||||
/* Tasks can be created statically or dynamically, so note
|
||||
this task had a statically allocated stack in case it is
|
||||
later deleted. The TCB was allocated dynamically. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY;
|
||||
|
||||
prvInitialiseNewTask( pxTaskDefinition->pvTaskCode,
|
||||
pxTaskDefinition->pcName,
|
||||
( uint32_t ) pxTaskDefinition->usStackDepth,
|
||||
pxTaskDefinition->pvParameters,
|
||||
pxTaskDefinition->uxPriority,
|
||||
pxCreatedTask, pxNewTCB,
|
||||
pxTaskDefinition->xRegions );
|
||||
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint16_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
TCB_t *pxNewTCB;
|
||||
BaseType_t xReturn;
|
||||
|
@ -656,15 +741,15 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
task was created dynamically in case it is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = pdFALSE;
|
||||
pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB );
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
|
@ -679,7 +764,14 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, TCB_t *pxNewTCB ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
TCB_t *pxNewTCB,
|
||||
const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
StackType_t *pxTopOfStack;
|
||||
UBaseType_t x;
|
||||
|
@ -805,6 +897,11 @@ UBaseType_t x;
|
|||
{
|
||||
vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth );
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* Avoid compiler warning about unreferenced parameter. */
|
||||
( void ) xRegions;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
|
||||
|
@ -1740,7 +1837,13 @@ BaseType_t xReturn;
|
|||
/* The Idle task is created using user provided RAM - obtain the
|
||||
address of the RAM then create the idle task. */
|
||||
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
|
||||
xIdleTaskHandle = xTaskCreateStatic( prvIdleTask, "IDLE", ulIdleTaskStackSize, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), pxIdleTaskStackBuffer, pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
|
||||
xIdleTaskHandle = xTaskCreateStatic( prvIdleTask,
|
||||
"IDLE",
|
||||
ulIdleTaskStackSize,
|
||||
( void * ) NULL,
|
||||
( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),
|
||||
pxIdleTaskStackBuffer,
|
||||
pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
|
||||
|
||||
if( xIdleTaskHandle != NULL )
|
||||
{
|
||||
|
@ -1754,7 +1857,11 @@ BaseType_t xReturn;
|
|||
#else
|
||||
{
|
||||
/* The Idle task is being created using dynamically allocated RAM. */
|
||||
xReturn = xTaskCreate( prvIdleTask, "IDLE", configMINIMAL_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
|
||||
xReturn = xTaskCreate( prvIdleTask,
|
||||
"IDLE", configMINIMAL_STACK_SIZE,
|
||||
( void * ) NULL,
|
||||
( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),
|
||||
&xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
|
@ -3486,24 +3593,36 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
}
|
||||
#endif /* configUSE_NEWLIB_REENTRANT */
|
||||
|
||||
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) )
|
||||
{
|
||||
/* The task can only have been allocated dynamically - free it
|
||||
again. */
|
||||
/* The task can only have been allocated dynamically - free both
|
||||
the stack and TCB. */
|
||||
vPortFree( pxTCB->pxStack );
|
||||
vPortFree( pxTCB );
|
||||
}
|
||||
#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
#elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 )
|
||||
{
|
||||
/* The task could have been allocated statically or dynamically, so
|
||||
check before attempting to free the memory. */
|
||||
if( pxTCB->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||
check what was statically allocated before trying to free the
|
||||
memory. */
|
||||
if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB )
|
||||
{
|
||||
/* Both the stack and TCB were allocated dynamically, so both
|
||||
must be freed. */
|
||||
vPortFree( pxTCB->pxStack );
|
||||
vPortFree( pxTCB );
|
||||
}
|
||||
else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY )
|
||||
{
|
||||
/* Only the stack was statically allocated, so the TCB is the
|
||||
only memory that must be freed. */
|
||||
vPortFree( pxTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Neither the stack nor the TCB were allocated dynamically, so
|
||||
nothing needs to be freed. */
|
||||
configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB )
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,7 +248,12 @@ static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseTy
|
|||
* Called after a Timer_t structure has been allocated either statically or
|
||||
* dynamically to fill in the structure's members.
|
||||
*/
|
||||
static void prvInitialiseNewTimer( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
static void prvInitialiseNewTimer( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTimerCreateTimerTask( void )
|
||||
|
@ -271,7 +276,13 @@ BaseType_t xReturn = pdFAIL;
|
|||
uint32_t ulTimerTaskStackSize;
|
||||
|
||||
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
|
||||
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, "Tmr Svc", ulTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, pxTimerTaskStackBuffer, pxTimerTaskTCBBuffer );
|
||||
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
|
||||
"Tmr Svc",
|
||||
ulTimerTaskStackSize,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
pxTimerTaskStackBuffer,
|
||||
pxTimerTaskTCBBuffer );
|
||||
|
||||
if( xTimerTaskHandle != NULL )
|
||||
{
|
||||
|
@ -280,7 +291,12 @@ BaseType_t xReturn = pdFAIL;
|
|||
}
|
||||
#else
|
||||
{
|
||||
xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", configTIMER_TASK_STACK_DEPTH, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );
|
||||
xReturn = xTaskCreate( prvTimerTask,
|
||||
"Tmr Svc",
|
||||
configTIMER_TASK_STACK_DEPTH,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
&xTimerTaskHandle );
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
}
|
||||
|
@ -296,7 +312,11 @@ BaseType_t xReturn = pdFAIL;
|
|||
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
Timer_t *pxNewTimer;
|
||||
|
||||
|
@ -324,7 +344,12 @@ BaseType_t xReturn = pdFAIL;
|
|||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
Timer_t *pxNewTimer;
|
||||
|
||||
|
@ -361,7 +386,12 @@ BaseType_t xReturn = pdFAIL;
|
|||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitialiseNewTimer( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, Timer_t *pxNewTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
static void prvInitialiseNewTimer( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
Timer_t *pxNewTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
/* 0 is not a valid value for xTimerPeriodInTicks. */
|
||||
configASSERT( ( xTimerPeriodInTicks > 0 ) );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue