Skip to main content
Explorer
March 11, 2024
Question

Rare UNALIGNED hard faults on STM32H753ZI

  • March 11, 2024
  • 2 replies
  • 1877 views

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
 
Disassembly code where execution stops:

 

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]

 

 
And register values:
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>		
 
This fault occurs randomly in intervals of few hours.
CCR->UNALIGN_TRP is set to 0.
 
I've read in errata that write-trough memory can cause some issues. Default memory type for internal flash of this MCU is write-through. Is it possible that the issue is related to this? 
 
Has anyone idea what can cause such issue? I will be greatfull for any hint.
 
 
 
    This topic has been closed for replies.

    2 replies

    Graduate II
    March 11, 2024

    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.

    Super User
    March 11, 2024

    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()

    kicurAuthor
    Explorer
    March 11, 2024

    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();
     }