diff --git a/components/freertos/include/freertos/FreeRTOSConfig.h b/components/freertos/include/freertos/FreeRTOSConfig.h index 81e8a7734..3ccd3fda6 100644 --- a/components/freertos/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/freertos/FreeRTOSConfig.h @@ -269,9 +269,7 @@ extern void vPortCleanUpTCB ( void *pxTCB ); #define configXT_BOARD 1 /* Board mode */ #define configXT_SIMULATOR 0 -#if CONFIG_ESP32_ENABLE_COREDUMP #define configENABLE_TASK_SNAPSHOT 1 -#endif #if CONFIG_SYSVIEW_ENABLE #ifndef __ASSEMBLER__ diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 0433deb2a..9126f862e 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -4991,22 +4991,24 @@ TickType_t uxReturn; #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 ) { @@ -5017,12 +5019,11 @@ TickType_t uxReturn; 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 @@ -5035,8 +5036,6 @@ TickType_t uxReturn; { 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 @@ -5052,12 +5051,11 @@ PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB[ portNUM_PROCESSORS ] = { NULL }; 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 ) { diff --git a/components/freertos/test/test_tasks_snapshot.c b/components/freertos/test/test_tasks_snapshot.c new file mode 100644 index 000000000..c9364cc18 --- /dev/null +++ b/components/freertos/test/test_tasks_snapshot.c @@ -0,0 +1,35 @@ +/* + Test FreeRTOS support for core dump. +*/ + +#include +#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); +}