Skip to content

Commit

Permalink
Merge branch 'bugfix/freertos_stack_tcb_alloc_order' into 'master'
Browse files Browse the repository at this point in the history
freertos: fix allocation order for stack and TCB per portSTACK_GROWTH

See merge request espressif/esp-idf!18042
  • Loading branch information
mahavirj committed May 11, 2022
2 parents 523c518 + 318f723 commit dec3db6
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
42 changes: 36 additions & 6 deletions components/freertos/FreeRTOS-Kernel/portable/port_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,24 @@ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
{
StaticTask_t *pxTCBBufferTemp;
StackType_t *pxStackBufferTemp;
//Allocate TCB and stack buffer in internal memory
pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t));
pxStackBufferTemp = pvPortMallocStackMem(configIDLE_TASK_STACK_SIZE);

/* If the stack grows down then allocate the stack then the TCB so the stack
* does not grow into the TCB. Likewise if the stack grows up then allocate
* the TCB then the stack. */
#if (portSTACK_GROWTH > 0)
{
//Allocate TCB and stack buffer in internal memory
pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t));
pxStackBufferTemp = pvPortMallocStackMem(configIDLE_TASK_STACK_SIZE);
}
#else /* portSTACK_GROWTH */
{
//Allocate TCB and stack buffer in internal memory
pxStackBufferTemp = pvPortMallocStackMem(configIDLE_TASK_STACK_SIZE);
pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t));
}
#endif /* portSTACK_GROWTH */

assert(pxTCBBufferTemp != NULL);
assert(pxStackBufferTemp != NULL);
//Write back pointers
Expand All @@ -184,9 +199,24 @@ void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
{
StaticTask_t *pxTCBBufferTemp;
StackType_t *pxStackBufferTemp;
//Allocate TCB and stack buffer in internal memory
pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t));
pxStackBufferTemp = pvPortMallocStackMem(configTIMER_TASK_STACK_DEPTH);

/* If the stack grows down then allocate the stack then the TCB so the stack
* does not grow into the TCB. Likewise if the stack grows up then allocate
* the TCB then the stack. */
#if (portSTACK_GROWTH > 0)
{
//Allocate TCB and stack buffer in internal memory
pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t));
pxStackBufferTemp = pvPortMallocStackMem(configTIMER_TASK_STACK_DEPTH);
}
#else /* portSTACK_GROWTH */
{
//Allocate TCB and stack buffer in internal memory
pxStackBufferTemp = pvPortMallocStackMem(configTIMER_TASK_STACK_DEPTH);
pxTCBBufferTemp = pvPortMallocTcbMem(sizeof(StaticTask_t));
}
#endif /* portSTACK_GROWTH */

assert(pxTCBBufferTemp != NULL);
assert(pxStackBufferTemp != NULL);
//Write back pointers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask );
* does not acquire any locks.
* @param[in] pxTask Task's handle
* @param[out] pxTaskSnapshot Snapshot of the task
* @return pdTRUE if operation was successful else pdFALSE
*/
void vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot );
BaseType_t vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot );

/**
* @brief Fill an array of TaskSnapshot_t structures for every task in the system
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,17 @@ TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask )
return pxNextTCB;
}

void vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot )
BaseType_t vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot )
{
configASSERT( portVALID_TCB_MEM(pxTask) );
configASSERT( pxTaskSnapshot != NULL );
if (portVALID_TCB_MEM(pxTask) == false || pxTaskSnapshot == NULL) {
return pdFALSE;
}

TCB_t *pxTCB = (TCB_t *)pxTask;
pxTaskSnapshot->pxTCB = pxTCB;
pxTaskSnapshot->pxTopOfStack = (StackType_t *)pxTCB->pxTopOfStack;
pxTaskSnapshot->pxEndOfStack = (StackType_t *)pxTCB->pxEndOfStack;
return pdTRUE;
}

UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArrayLength, UBaseType_t * const pxTCBSize )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ TEST_CASE("Task snapshot: Iterate", "[freertos]")
TaskHandle_t cur_task_handle = pxTaskGetNext(NULL);
while (cur_task_handle != NULL) {
// Get the task's snapshot
vTaskGetSnapshot(cur_task_handle, &task_snapshots[num_snapshots]);
BaseType_t Result = vTaskGetSnapshot(cur_task_handle, &task_snapshots[num_snapshots]);
TEST_ASSERT_EQUAL(pdTRUE, Result);
num_snapshots++;
cur_task_handle = pxTaskGetNext(cur_task_handle);
}
Expand Down
1 change: 1 addition & 0 deletions docs/en/migration-guides/freertos.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Tasks Snapshot

The header ``task_snapshot.h`` has been removed from ``freertos/task.h``. ESP-IDF developers should include ``"freertos/task_snapshot.h``` in case they need tasks snapshot API.

The function :cpp:func:`vTaskGetSnapshot` now returns ``BaseType_t``. Return value shall be ``pdTRUE`` on success and ``pdFALSE`` otherwise.

FreeRTOS Asserts
----------------
Expand Down

0 comments on commit dec3db6

Please sign in to comment.