Hardfault when execute xTaskResumeAll in tmr svc

The call path as follows,

image

prvTimerTask->prvProcessTimerOrBlockTask → xTaskResumeAll → listREMOVE_ITEM( &( pxTCB->xEventListItem ) )

Any suggestions?

This likely is a memory corruption. Which hardware are you using? Have you tried common debugging techniques like defining configASSERT, enabling stack overflow checking etc. as described here - FreeRTOS - Open Source RTOS Kernel for small embedded systems

Hello,

The demo has defined configASSERT and enabled stack overflow checking(2). but cannot detect the issue. It’s a ramdom issue within two hours stress test.

This also indicates towards some memory corruption. Try setting configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES to 1 in your FreeRTOSConfig.h.

Another thing to try is to turn off functionality off your application one by one to narrow down the problematic part.

Ok, got it. let me enable the config configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES to check it.

Hi Gaurav,

The config also cannot detect the issue. Hardfault is also happen.


Don’t know why the suspended task’s xEventListItem.pvContainer is NULL?(other suspended task’s xEventListItem.pvContainer is not NULL)

Please provide the following -

  1. What hardware are you using?
  2. Share your FreeRTOSConfig.h.
  3. How many ISRs are there in your application that call FreeRTOS APIs?
  4. Is it possible for you to share code?

Hi Gaurav,

  1. Current the hardware is nxp internal product, it’s based on cortex-m33.
  2. FreeRTOSConfig.h
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#define configUSE_PREEMPTION 1
#define configUSE_TICKLESS_IDLE 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ (SystemCoreClock)
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES (15)
#define configMINIMAL_STACK_SIZE ((unsigned short)256)
#define configTOTAL_HEAP_SIZE ((size_t)(40 * 1024))
#define configMAX_TASK_NAME_LEN (10)
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TIME_SLICING 0
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES (2)

/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (10)
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 0
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTimerPendFunctionCall 1
#define taskDISABLE_INTERRUPTS()           portDISABLE_INTERRUPTS()
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT(x)           \
    if ((x) == 0)                 \
    {                             \
        taskDISABLE_INTERRUPTS(); \
        for (;;)                  \
            ;                     \
    }



#if defined(__ICCARM__)||defined(__CC_ARM)||defined(__GNUC__)
    /* Clock manager provides in this variable system core clock frequency */
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif


#ifndef configENABLE_FPU
  #define configENABLE_FPU                        1
#endif
#ifndef configENABLE_MPU
  #define configENABLE_MPU                        0
#endif
#ifndef configENABLE_TRUSTZONE
  #define configENABLE_TRUSTZONE                  0
#endif
#ifndef configRUN_FREERTOS_SECURE_ONLY
  #define configRUN_FREERTOS_SECURE_ONLY          1
#endif

/* Redefine: Mutex is needed for SRTM communication */
#undef configUSE_MUTEXES
#define configUSE_MUTEXES                       1

#ifndef configTOTAL_HEAP_SIZE
#define configTOTAL_HEAP_SIZE ((size_t)(40 * 1024))
#endif

/* Interrupt nesting behaviour configuration. Cortex-M specific. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 3 /* 7 priority levels */
#endif

#define configSTACK_DEPTH_TYPE uint32_t

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1U << (configPRIO_BITS)) - 1)

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))

#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define vPortPendSVHandler PendSV_Handler
#define vPortSysTickHandler SysTick_Handler

#endif /* FREERTOS_CONFIG_H */
  1. Only DMA ISR

Typical causes of what you see are the following:

  • incorrect implementation/usage of the critical section in a custom port
  • incorrect assignment of interrupt priorities, in particular pending svc and timer interrupts
  • interrupts not using xxxFromISR APIs
  • interrupts above max syscall priority using OS services.

What is the priority of DMA interrupt?

DMA interrput priority is 5

ok, let me check them again.

Hi Gaurav and RAc,

This is my analysis, any suggestions?
dma isr
xQueueGenericSendFromISR
xTaskRemoveFromEventList
listREMOVE_ITEM( &( pxUnblockedTCB->xEventListItem ) ); (currently xEventListItem.pvContainer == NULL)
listINSERT_END( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); (add xEventListItem to xPendingReadyList)

ILDE Task/Timer Task
xTaskResumeAll
pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) );
listREMOVE_ITEM( &( pxTCB->xEventListItem ) );
( pxList->uxNumberOfItems )-- /* hardfault in here(pxList is NULL, pxList is xEventListItem.pxContainer) */

It looks as if your dma isr is running on a priority hiher than max syscall yet uses FreeRTOS APIs. That is not allowed, even though the correct API set (xxxFromISR) is used.

Hi @RAc
The DMA isr’s priority is 5(not shifted, after shifted, the value is 0xA0).
configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 0x40.
0x40 < 0xA0, so the priorify of dma is lower than max syscall?

That seems right. Can you try disabling the functionalities of your application one by one to narrow down the problematic part?

hi Gaurav,

ok, got it. Thanks.