2022-11-24 12:41 AM
Hi,
I am testing ThresholdDetection example of FlightSense on Nucleo_STM32F401RE, the code works fine with default setting as 4x4 resolution in MX_53L5A1_ThresholdDetection_Process(). Changing resolution to 8x8, printf() goes into HardFault_Handler(), from debug console the instruction prior to exception handler is _malloc_r() accessing 0x800000 address. Increasing both heap and stack size to 0x8000 does not help.
However, adding printf() in main.c (i.e. prior to running MX_53L5A1_ThresholdDetection_Process()), the code works fine without exception.
My questions: (1) why printf() accessed invalid memory address after changing 4x4 to 8x8? (2) why adding printf() in main.c resolved it without exception? (3) how to identify the root cause?
Any help and suggestion is pretty appreciated.
Thanks~
2022-11-24 06:43 AM
2022-11-24 09:07 PM
Hi Pavel,
Thanks for response.
Referred to https://community.st.com/s/question/0D50X0000CBmXufSQF/newlibmalloc-locking-mechanism-to-be-threadsafe I replace sysmem.c to be thread-safe. Setting breakpoint at _critical_section_enter() I confirm the code calls into _malloc_lock(), however the program runs to HardFault_Handler() right after returning from _malloc_lock(). Stepping to next instructions (at 0x0800C342) after _malloc_lock(), it tries to access memory 0x800000 pointed by r6 (or 0x20002250).
disassembly of _malloc_r below
_malloc_r:
0800c315: stmdb sp!, {r4, r5, r6, r7, r8, lr}
0800c319: adds r5, r1, #3
0800c31b: bic.w r5, r5, #3
0800c31f: adds r5, #8
0800c321: cmp r5, #12
0800c323: it cc
0800c325: movcc r5, #12
0800c327: cmp r5, #0
0800c329: mov r7, r0
0800c32b: blt.n 0x800c330 <_malloc_r+28>
0800c32d: cmp r1, r5
0800c32f: bls.n 0x800c33c <_malloc_r+40>
0800c331: movs r3, #12
0800c333: str r3, [r7, #0]
0800c335: movs r6, #0
0800c337: mov r0, r6
0800c339: ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
0800c33d: ldr r6, [pc, #184] ; (0x800c3f8 <_malloc_r+228>)
0800c33f: bl 0x8001ea8 <__malloc_lock>
0800c343: ldr r3, [r6, #0]
0800c345: mov r4, r3
0800c347: cbnz r4, 0x800c396 <_malloc_r+130>
0800c349: mov r1, r5
0800c34b: mov r0, r7
0800c34d: bl 0x800c2d4 <sbrk_aligned>
......
If I change sensor resolution from 8x8 to 4x4, the memory pointed by r6 of the same instruction is 0x0 at this time, the code runs without any problem.
Any clue or suggestion to figure out the root cause is much appreciated!
Thanks,
Sean
2022-11-27 09:52 PM
I found the root cause is illegal access to memory out of the declared thresholds[64] array. Everything is just fine for 4x4 resolution, however the code tries to access thresholds[64] in case of 8x8 zone resolution, which is conflicted to a pointer (e.g. 0x20002250) used in _malloc_r(). The content is rewritten to 0x800000 and therefore accessing to such memory address results into an exception.