Hard faults with FreeRTOS

gkovelman wrote on Thursday, August 14, 2014:

Hi,
I’m trying to evaluate (and then integrate) FreeRTOS on STM32F401 Discovery board. I’m using the libraries provided by STM32CubeMX.
My peripheral setup has 1 I2C 1 UART, and 1 ext. interrupt.
My code has 1 task and that task has call to proprietary library calls that use I2C in DMA mode, send data over UART in blocking mode and sometimes check for a value from the ext. interrupt.
The problem is that I have frequent Precise errors and less frequent Unaligned and Imprecise errors. These errors, or any errors, don’t occur when FreeRTOS is disabled.
The lines where the errors occur are rather consistent and the following are examples:

  1. At (FreeRTOS) tasks.c line 1704:
    :::C++
            if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( unsigned portBASE_TYPE ) 1 )

Failing assembly code at 0x800a6fc since R0 contains: 0x20148EBC
:::asm

??xTaskIncrementTick_5:
    0x800a6ea: 0xf8df 0x0284  LDR.W     R0, ??DataTable29_1     ; pxReadyTasksLists
    0x800a6ee: 0xf8df 0x127c  LDR.W     R1, ??DataTable29       ; pxCurrentTCB
    0x800a6f2: 0x6809         LDR       R1, [R1]
    0x800a6f4: 0x6ac9         LDR       R1, [R1, #0x2c]
    0x800a6f6: 0x2214         MOVS      R2, #20                 ; 0x14
    0x800a6f8: 0xfb02 0x0001  MLA       R0, R2, R1, R0
    0x800a6fc: 0x6800         LDR       R0, [R0]
    0x800a6fe: 0x2802         CMP       R0, #2
    0x800a700: 0xd309         BCC.N     ??xTaskIncrementTick_11 ; 0x800a716
  1. At my code:
    :::C++
    if (i2c_read(st.hw->addr, st.reg->raw_compass, 8, tmp))

Failing code at address 0x80042a8 since R0 contains: 0xFF8D0000
:::asm

??mpu_get_compass_reg_0:
    0x80042a0: 0xab00         ADD       R3, SP, #0x0
    0x80042a2: 0x2208         MOVS      R2, #8
    0x80042a4: 0x486c         LDR.N     R0, ??DataTable51       ; st
    0x80042a6: 0x6800         LDR       R0, [R0]
    0x80042a8: 0xf890 0x1028  LDRB.W    R1, [R0, #0x28]
    0x80042ac: 0x486a         LDR.N     R0, ??DataTable51       ; st
    0x80042ae: 0x6840         LDR       R0, [R0, #0x4]
    0x80042b0: 0x7800         LDRB      R0, [R0]
    0x80042b2: 0xf000 0xf988  BL        Sensors_I2C_ReadRegister_swap ; 0x80045c6
    0x80042b6: 0x2800         CMP       R0, #0

I’m rather new with STM32 and with FreeRTOS so I’ve been trying the following:

  1. Change I2C/UART to DMA mode/to blocking mode
  2. Change priorities of interrupt to lower/higher than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
    But that didn’t do the trick.

Could it be that R0 register isn’t saved when context switching? Any ideas on how to debug this further?

davedoors wrote on Thursday, August 14, 2014:

Could it be that R0 register isn’t saved when context switching

No. The hardware saves that itself.

Do you have configASSERT() defined?

gkovelman wrote on Thursday, August 14, 2014:

Yes, it’s in FreeRTOSConfig.h, as provided by STM Cube.

gkovelman wrote on Monday, August 18, 2014:

So the problem was with the stack size. For some applications, 128 bytes are not enough.