#endif /* configUSE_TASK_NOTIFICATIONS */
#if ( configENABLE_TASK_SNAPSHOT == 1 )
-
- static void prvTaskGetSnapshot( TaskSnapshot_t *pxTaskSnapshotArray, UBaseType_t *uxTask, TCB_t *pxTCB )
- {
- pxTaskSnapshotArray[ *uxTask ].pxTCB = pxTCB;
- pxTaskSnapshotArray[ *uxTask ].pxTopOfStack = (StackType_t *)pxTCB->pxTopOfStack;
- #if( portSTACK_GROWTH < 0 )
- {
- pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxEndOfStack;
- }
- #else
- {
- pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxStack;
- }
- #endif
- (*uxTask)++;
- }
+ static void prvTaskGetSnapshot( TaskSnapshot_t *pxTaskSnapshotArray, UBaseType_t *uxTask, TCB_t *pxTCB )
+ {
+ if (pxTCB == NULL) {
+ return;
+ }
+ pxTaskSnapshotArray[ *uxTask ].pxTCB = pxTCB;
+ pxTaskSnapshotArray[ *uxTask ].pxTopOfStack = (StackType_t *)pxTCB->pxTopOfStack;
+ #if( portSTACK_GROWTH < 0 )
+ {
+ pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxEndOfStack;
+ }
+ #else
+ {
+ pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxStack;
+ }
+ #endif
+ (*uxTask)++;
+ }
static void prvTaskGetSnapshotsFromList( TaskSnapshot_t *pxTaskSnapshotArray, UBaseType_t *uxTask, const UBaseType_t uxArraySize, List_t *pxList )
{
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
do
{
- listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
-
if( *uxTask >= uxArraySize )
break;
- prvTaskGetSnapshot( pxTaskSnapshotArray, uxTask, pxNextTCB );
+ listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
+ prvTaskGetSnapshot( pxTaskSnapshotArray, uxTask, pxNextTCB );
} while( pxNextTCB != pxFirstTCB );
}
else
{
UBaseType_t uxTask = 0, i = 0;
-PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB[ portNUM_PROCESSORS ] = { NULL };
-
*pxTcbSz = sizeof(TCB_t);
/* Fill in an TaskStatus_t structure with information on each
task in the Blocked state. */
prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, ( List_t * ) pxDelayedTaskList );
prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, ( List_t * ) pxOverflowDelayedTaskList );
- for (i = 0; i < portNUM_PROCESSORS; i++) {
- if( uxTask >= uxArraySize )
- break;
- prvTaskGetSnapshot( pxTaskSnapshotArray, &uxTask, pxCurrentTCB[ i ] );
- prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, &( xPendingReadyList[ i ] ) );
- }
+ for (i = 0; i < portNUM_PROCESSORS; i++) {
+ if( uxTask >= uxArraySize )
+ break;
+ prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, &( xPendingReadyList[ i ] ) );
+ }
#if( INCLUDE_vTaskDelete == 1 )
{
--- /dev/null
+/*
+ Test FreeRTOS support for core dump.
+*/
+
+#include <stdio.h>
+#include "soc/cpu.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "unity.h"
+
+#define TEST_MAX_TASKS_NUM 32
+
+/* simple test to check that in normal conditions uxTaskGetSnapshotAll does not generate exception */
+TEST_CASE("Tasks snapshot", "[freertos]")
+{
+ TaskSnapshot_t tasks[TEST_MAX_TASKS_NUM];
+ UBaseType_t tcb_sz;
+ int other_core_id = xPortGetCoreID() == 0 ? 1 : 0;
+
+ // uxTaskGetSnapshotAll is supposed to be called when all tasks on both CPUs are
+ // inactive and can not alter FreeRTOS internal tasks lists, e.g. from panic handler
+ unsigned state = portENTER_CRITICAL_NESTED();
+#if CONFIG_FREERTOS_UNICORE == 0
+ esp_cpu_stall(other_core_id);
+#endif
+ UBaseType_t task_num = uxTaskGetSnapshotAll(tasks, TEST_MAX_TASKS_NUM, &tcb_sz);
+#if CONFIG_FREERTOS_UNICORE == 0
+ esp_cpu_unstall(other_core_id);
+#endif
+ portEXIT_CRITICAL_NESTED(state);
+
+ printf("Dumped %d tasks. TCB size %d\n", task_num, tcb_sz);
+ TEST_ASSERT_NOT_EQUAL(0, task_num);
+ TEST_ASSERT_NOT_EQUAL(0, tcb_sz);
+}