Hard faults with FreeRTOS
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( listCURRENTLISTLENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( unsigned portBASETYPE ) 1 )
~~~~~~
Failing assembly code at 0x800a6fc since R0 contains: 0x20148EBC
:::asm
~~~~~~
??xTaskIncrementTick5:
0x800a6ea: 0xf8df 0x0284 LDR.W R0, ??DataTable291 ; 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 ??xTaskIncrementTick11 ; 0x800a716
~~~~~~
2) At my code:
:::C++
~~~~~~
if (i2cread(st.hw->addr, st.reg->rawcompass, 8, tmp))
~~~~~~
Failing code at address 0x80042a8 since R0 contains: 0xFF8D0000
:::asm
~~~~~~
??mpugetcompassreg0:
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 SensorsI2CReadRegister_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 configLIBRARYMAXSYSCALLINTERRUPTPRIORITY
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?
Hard faults with FreeRTOS
Could it be that R0 register isn’t saved when context switchingNo. The hardware saves that itself. Do you have configASSERT() defined?
Hard faults with FreeRTOS
Yes, it’s in FreeRTOSConfig.h, as provided by STM Cube.
Hard faults with FreeRTOS
So the problem was with the stack size. For some applications, 128 bytes are not enough.