cancel
Showing results for 
Search instead for 
Did you mean: 

Rare UNALIGNED hard faults on STM32H753ZI

kicur
Associate II

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.
 
 
 
3 REPLIES 3

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Evangelist III

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

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