Support for optionally allocating stacks separate from the heap.

A new configuration macro (configSUPPORT_SEPARATE_STACK_ALLOCATION)
was added to allow stack allocation calls in tasks.c to be redirected
to a new portable layer allocation function.  This allows a client to
opt to add a separate stack allocator for dynamic stack allocation.
The default is the current behavior, which is to allocate stacks with
pvPortMalloc.
This commit is contained in:
Eli Boling 2021-02-12 11:15:14 -05:00
parent 5b9549ab82
commit 627839b0ab
3 changed files with 18 additions and 5 deletions

View file

@ -896,6 +896,11 @@
#define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1
#endif #endif
#ifndef configSUPPORT_SEPARATE_STACK_ALLOCATION
/* Defaults to 0 for backward compatibility. */
#define configSUPPORT_SEPARATE_STACK_ALLOCATION 0
#endif
#ifndef configSTACK_DEPTH_TYPE #ifndef configSTACK_DEPTH_TYPE
/* Defaults to uint16_t for backward compatibility, but can be overridden /* Defaults to uint16_t for backward compatibility, but can be overridden

View file

@ -179,6 +179,14 @@ void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
#if( configSUPPORT_SEPARATE_STACK_ALLOCATION == 1 )
void *pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFreeStack( void *pv ) PRIVILEGED_FUNCTION;
#else
#define pvPortMallocStack pvPortMalloc
#define vPortFreeStack vPortFree
#endif
/* /*
* Setup the hardware ready for the scheduler to take control. This generally * Setup the hardware ready for the scheduler to take control. This generally
* sets up a tick interrupt and sets timers for the correct tick frequency. * sets up a tick interrupt and sets timers for the correct tick frequency.

10
tasks.c
View file

@ -748,7 +748,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
/* 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 = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
if( pxNewTCB->pxStack == NULL ) if( pxNewTCB->pxStack == NULL )
{ {
@ -763,7 +763,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
StackType_t * pxStack; StackType_t * pxStack;
/* Allocate space for the stack used by the task being created. */ /* Allocate space for the stack used by the task being created. */
pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */ pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */
if( pxStack != NULL ) if( pxStack != NULL )
{ {
@ -779,7 +779,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
{ {
/* The stack cannot be used as the TCB was not created. Free /* The stack cannot be used as the TCB was not created. Free
* it again. */ * it again. */
vPortFree( pxStack ); vPortFreeStack( pxStack );
} }
} }
else else
@ -3950,7 +3950,7 @@ static void prvCheckTasksWaitingTermination( void )
{ {
/* The task can only have been allocated dynamically - free both /* The task can only have been allocated dynamically - free both
* the stack and TCB. */ * the stack and TCB. */
vPortFree( pxTCB->pxStack ); vPortFreeStack( pxTCB->pxStack );
vPortFree( pxTCB ); vPortFree( pxTCB );
} }
#elif ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ #elif ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
@ -3962,7 +3962,7 @@ static void prvCheckTasksWaitingTermination( void )
{ {
/* Both the stack and TCB were allocated dynamically, so both /* Both the stack and TCB were allocated dynamically, so both
* must be freed. */ * must be freed. */
vPortFree( pxTCB->pxStack ); vPortFreeStack( pxTCB->pxStack );
vPortFree( pxTCB ); vPortFree( pxTCB );
} }
else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY )