2024-03-11 11:56 AM
I have project on STM32H753ZI and I am using ADC in DMA mode. Every few hours I get Usage Fault Unaligned access hard fault. Fault is invoked in my ADC_ConvCptlCallback in which depending on ADC value I decide about GPO state
Stack during HardFault:
HardFault_Handler() at stm32h7xx_it.c:91 0x80040ca
<signal handler called>() at 0xfffffff1
adc_adapter_handle_adc_sample() at communication-service.c:59 0x8084c34
HAL_ADC_ConvCpltCallback() at main.c:364 0x80024a8
ADC_DMAConvCplt() at stm32h7xx_hal_adc.c:3,865 0x8006482
HAL_DMA_IRQHandler() at stm32h7xx_hal_dma.c:1,384 0x8008eb4
DMA1_Stream0_IRQHandler() at stm32h7xx_it.c:189 0x800410a
<signal handler called>() at 0xfffffffd
prvCheckTasksWaitingTermination() at tasks.c:3,650 0x801611c
prvIdleTask() at tasks.c:3,409 0x801603c
08084c1c: b.n 0x8084c34 <adc_adapter_handle_adc_sample+148>
54 } else if (adc_adapter.adc_current < adc_adapter.adc_low) {
08084c1e: ldr r3, [pc, #24] ; (0x8084c38 <adc_adapter_handle_adc_sample+152>)
08084c20: ldr r2, [r3, #0]
08084c22: ldr r3, [pc, #20] ; (0x8084c38 <adc_adapter_handle_adc_sample+152>)
08084c24: ldr r3, [r3, #24]
08084c26: cmp r2, r3
08084c28: bcs.n 0x8084c34 <adc_adapter_handle_adc_sample+148>
55 HAL_GPIO_WritePin(BUS_MK_GPIO_Port, BUS_MK_Pin, GPIO_PIN_SET);
08084c2a: movs r2, #1
08084c2c: movs r1, #16
08084c2e: ldr r0, [pc, #12] ; (0x8084c3c <adc_adapter_handle_adc_sample+156>)
08084c30: bl 0x800aacc <HAL_GPIO_WritePin>
59 }
08084c34: nop
08084c36: pop {r7, pc}
08084c38: ldrsb r4, [r6, r1]
08084c3a: movs r4, #6
08084c3c: lsrs r0, r0, #16
08084c3e: ldr r2, [r0, r0]
General Registers General Purpose and FPU Register Group r0 603991516 r1 604396596 r2 768 r3 0 r4 -1515870811 r5 -1515870811 r6 -1515870811 r7 604503928 r8 -1515870811 r9 -1515870811 r10 -1515870811 r11 -1515870811 r12 -1515870811 sp 0x2407ff78 lr 134227113 pc 0x8084c34 <adc_adapter_handle_adc_sample+148> xpsr 1610612763 d0 0 d1 0 d2 0 d3 10 d4 0.50000401634281388 d5 10 d6 1.7976931348623157e+308 d7 0 d8 0 d9 0 d10 0 d11 0 d12 0 d13 0 d14 0 d15 -nan(0xfffff00000000) fpscr 1610612752 msp 0x2407ff78 psp 0x240042f0 <Idle_Stack.2+1976>
2024-03-11 12:19 PM
Probably the stack frame getting corrupted
Watch for large auto/local foot print in call-tree, especially within call-back
Unaligned typical with LDM / LDRD / STM / STRD type operations to non 32-bit aligned addresses.
Say doubles to unaligned pointer reference.
2024-03-11 01:38 PM
> Disassembly code where execution stops:
Can you show few more code lines before address 08084c1c? Better from the beginning of adc_adapter_handle_adc_sample()
2024-03-11 02:33 PM
Thanks for the answer. I've just realized that by mistake I configured my ram memory as device type so unalinged memory access should cause hard fault error. I will try to set it to normal type and see if it happen again but I need time to confirm it.
But still I don't know why it wasn't invoked immediatly but only after some time of execution. The program was running in all if() paths so every instruction was invoked multiple times and variables allocation didn't change.
This is code from the beginning of the function but from different build so addresses changed a little:
29 void adc_adapter_handle_adc_sample() {
adc_adapter_handle_adc_sample:
08084d24: push {r7, lr}
08084d26: add r7, sp, #0
30 if (adc_adapter.adc_log_flag) {
08084d28: ldr r3, [pc, #144] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d2a: ldrb.w r3, [r3, #33] ; 0x21
08084d2e: cmp r3, #0
08084d30: beq.n 0x8084d68 <adc_adapter_handle_adc_sample+68>
32 if (adc_adapter.adc_log_counter++ >=adc_adapter.adc_log_offset) {
08084d32: ldr r3, [pc, #136] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d34: ldr r3, [r3, #8]
08084d36: adds r2, r3, #1
08084d38: ldr r1, [pc, #128] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d3a: str r2, [r1, #8]
08084d3c: ldr r2, [pc, #124] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d3e: ldr r2, [r2, #36] ; 0x24
08084d40: cmp r3, r2
08084d42: bcc.n 0x8084d68 <adc_adapter_handle_adc_sample+68>
33 if (adc_adapter.adc_log_saved_count < ADC_LOG_LENGTH) {
08084d44: ldr r3, [pc, #116] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d46: ldr r3, [r3, #12]
08084d48: movw r2, #49999 ; 0xc34f
08084d4c: cmp r3, r2
08084d4e: bhi.n 0x8084d68 <adc_adapter_handle_adc_sample+68>
34 adc_adapter.adc_log[adc_adapter.adc_log_saved_count++] = adc_adapter.adc_current;
08084d50: ldr r3, [pc, #104] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d52: ldr r2, [r3, #4]
08084d54: ldr r3, [pc, #100] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d56: ldr r3, [r3, #12]
08084d58: adds r1, r3, #1
08084d5a: ldr r0, [pc, #96] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d5c: str r1, [r0, #12]
08084d5e: lsls r3, r3, #2
08084d60: add r3, r2
08084d62: ldr r2, [pc, #88] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d64: ldr r2, [r2, #0]
08084d66: str r2, [r3, #0]
45 if (adc_adapter.adc_read_flag) {
08084d68: ldr r3, [pc, #80] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d6a: ldrb.w r3, [r3, #32]
08084d6e: cmp r3, #0
08084d70: beq.n 0x8084db8 <adc_adapter_handle_adc_sample+148>
48 if (adc_adapter.adc_current> adc_adapter.adc_high) {
08084d72: ldr r3, [pc, #72] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d74: ldr r2, [r3, #0]
08084d76: ldr r3, [pc, #68] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d78: ldr r3, [r3, #28]
08084d7a: cmp r2, r3
08084d7c: bls.n 0x8084da2 <adc_adapter_handle_adc_sample+126>
49 if (adc_adapter.adc_log_offset == -1) {
08084d7e: ldr r3, [pc, #60] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d80: ldr r3, [r3, #36] ; 0x24
08084d82: cmp.w r3, #4294967295
08084d86: bne.n 0x8084d96 <adc_adapter_handle_adc_sample+114>
50 adc_adapter.adc_log_flag = true;
08084d88: ldr r3, [pc, #48] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d8a: movs r2, #1
08084d8c: strb.w r2, [r3, #33] ; 0x21
51 adc_adapter.adc_log_offset = 0;
08084d90: ldr r3, [pc, #40] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084d92: movs r2, #0
08084d94: str r2, [r3, #36] ; 0x24
53 HAL_GPIO_WritePin(BUS_MK_GPIO_Port, BUS_MK_Pin, GPIO_PIN_RESET);
08084d96: movs r2, #0
08084d98: movs r1, #16
08084d9a: ldr r0, [pc, #36] ; (0x8084dc0 <adc_adapter_handle_adc_sample+156>)
08084d9c: bl 0x800ac2c <HAL_GPIO_WritePin>
59 }
08084da0: b.n 0x8084db8 <adc_adapter_handle_adc_sample+148>
54 } else if (adc_adapter.adc_current < adc_adapter.adc_low) {
08084da2: ldr r3, [pc, #24] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084da4: ldr r2, [r3, #0]
08084da6: ldr r3, [pc, #20] ; (0x8084dbc <adc_adapter_handle_adc_sample+152>)
08084da8: ldr r3, [r3, #24]
08084daa: cmp r2, r3
08084dac: bcs.n 0x8084db8 <adc_adapter_handle_adc_sample+148>
55 HAL_GPIO_WritePin(BUS_MK_GPIO_Port, BUS_MK_Pin, GPIO_PIN_SET);
08084dae: movs r2, #1
08084db0: movs r1, #16
08084db2: ldr r0, [pc, #12] ; (0x8084dc0 <adc_adapter_handle_adc_sample+156>)
08084db4: bl 0x800ac2c <HAL_GPIO_WritePin>
59 }
08084db8: nop
08084dba: pop {r7, pc}
08084dbc: ldrsb r4, [r6, r1]
08084dbe: movs r4, #6
08084dc0: lsrs r0, r0, #16
08084dc2: ldr r2, [r0, r0]
adc_adapter struct:
struct adc_adapter {
uint32_t adc_current;
uint32_t* adc_log;
uint32_t adc_log_counter;
uint32_t adc_log_saved_count;
uint32_t adc_base;
bool adc_base_set;
uint32_t adc_low;
uint32_t adc_high;
bool adc_read_flag;
bool adc_log_flag;
long adc_log_offset;
bool init;
};
and ADC start function:
if (HAL_ADC_Start_DMA(&hadc1, &(adc_adapter_get_singleton()->adc_current), 1) != HAL_OK) {
Error_Handler();
}