STM32F401 hard fault at boot time - Page 1
Forum section: electronics / general

author: old gregg
author_rank: Regular Contributor
timestamp: October 24, 2021, 06:45:50 pm
content: HI,I'm having an issue with a stm32F401CCU6. The MCU crashes right after the "SystemInit" called at startup. I stepped through the SetSysClock() with no issues. Once the function is done, it goes in the hardfault_handler interrupt.Code:void SystemInit(void){/* FPU settings ------------------------------------------------------------*/#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */#endif/* Reset the RCC clock configuration to the default reset state ------------*//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset CFGR register */RCC->CFGR = 0x00000000;/* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset PLLCFGR register */RCC->PLLCFGR = 0x24003010;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Disable all interrupts */RCC->CIR = 0x00000000;#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl();#endif /* DATA_IN_ExtSRAM *//* Configure the System clock source, PLL Multiplier and Divider factors,AHB/APBx prescalers and Flash settings ----------------------------------*/SetSysClock();/* Configure the Vector Table location add offset address ------------------*/#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */#endif}At first I though this was a badly configure location to the flash VTOR register above. But the code seems to be correct by default and the map file gives the correct locationsCode:Memory ConfigurationName Origin Length AttributesFLASH 0x0000000008000000 0x0000000000040000 xrRAM 0x0000000020000000 0x0000000000010000 xrwMEMORY_B1 0x0000000060000000 0x0000000000000000 xrCCMRAM 0x0000000010000000 0x0000000000010000 rw*default* 0x0000000000000000 0xffffffffffffffff.I'm open to suggestion, it's very frustrating it's the first time I'm having issues like this with STM32.thanks

author: ataradov
author_rank: Super Contributor
timestamp: October 24, 2021, 06:54:01 pm
content: First of all, step though the assembly and see if there is a specific instruction that causes the issue.And then check the values of the following registers:SCB->CFSR; // Configurable Fault Status Register (MMSR, BFSR and UFSR)SCB->HFSR; // Hard Fault Status RegisterSCB->DFSR; // Debug Fault Status RegisterSCB->MMFAR; // MemManage Fault Address RegisterSCB->BFAR; // Bus Fault Address RegisterSCB->AFSR; // Auxiliary Fault Status RegisterThose registers will contain quite a bit of information about the fault.

author: old gregg
author_rank: Regular Contributor
timestamp: October 24, 2021, 08:07:48 pm
content: Hi Ataradov !here are the register,CFSR : INVSTATEHFSR : FORCEDDFSR : VCATCH | HALTEDMMFAR : 0xe000edf8precise data Violation (PRECISERR)BFAR : 0x20010000 (is it in RAM ?)the chip is :SRAM size : 64KiBFLASH size : 256KiBchip id : 00000423Core id : 2ba01477

author: ataradov
author_rank: Super Contributor
timestamp: October 24, 2021, 08:19:13 pm
content: INVSTATE means that something tried to jump to a non-thumb code.The addresses 0xe000edf8 and 0x20010000 are suspicious. Especially the first one. The second one - it looks like some instruction is trying to do something past the physical SRAM. But since it is a precise fault, it should be easy enough to figure out once you get to the disassembly single stepping.

author: ataradov
author_rank: Super Contributor
timestamp: October 24, 2021, 08:23:42 pm
content: Also, what is VECT_TAB_OFFSET? Different MCUs have different requirements on its alignment. ARM requires at least 128 bytes, but I've seen cases where 1K is required.If your table is in the flash, try to not write VTOR at all.

author: emece67
author_rank: Frequent Contributor
timestamp: October 24, 2021, 10:02:51 pm
content: .

author: abyrvalg
author_rank: Frequent Contributor
timestamp: October 24, 2021, 10:16:25 pm
content: Also you can find out the failed instruction address from the stack frame. SP should point to saved R0-R3, R12, LR, PC, PSR, so check [SP+0x18].

author: Psi
author_rank: Super Contributor
timestamp: October 24, 2021, 10:23:26 pm
content: Do you have all the boot pins connected correctly. If you accidently leave one floating weird stuff can happen at boot due to startup power draw glitching the input.

author: bson
author_rank: Unknown
timestamp: October 25, 2021, 01:10:32 am
content: Note that FPCCR.ASPEN and FPCCR.LSPEN are both set to 1 on reset. So the processor will save FPU context on the stack on exceptions if you have executed a floating point instruction. (Or that's my take on it.) I'd clear those FPCCR bits if you don't expect to find this state on the stack or never use the FPU in interrupt handlers (so only need to save and load it on context switches).

author: old gregg
author_rank: Regular Contributor
timestamp: October 25, 2021, 11:19:50 am
content: Ok buying the board on aliexpress, I though it was a barebone micro on a DIP adapter, but no it apparently has a bootloader at the begining of the flash.https://github.com/WeActTC/MiniSTM32F4x1

author: bingo600
author_rank: Super Contributor
timestamp: October 25, 2021, 08:36:09 pm
content: But wouldn't a succesfull dfu-load sequence "blow" any preloaded bootloader right out of the flash ??How did you initially load your own code onto the board ?/Bingo

author: ataradov
author_rank: Super Contributor
timestamp: October 25, 2021, 09:14:38 pm
content: They seem to provide some GUI tool, that bootloader most likely takes the binary and puts it after itself, so it would never overwrite itself.How did debugging work is a question though. But I assume bootloader may have been debugged instead of the actual application. Execution flow would not make sense, but it is easy to miss, given that bootloader itself was missed.

author: westfw
author_rank: Super Contributor
timestamp: October 25, 2021, 11:10:17 pm
content: QuoteIt's worse than that. ARM requires that the table be aligned to the next power of two above the actual size of the vector table. That's always at least 128bytes as indicated by the 6 "always zero" bits, but it's usually a significantly higher number on CM3 and CM4 chips. THr STM32F401 datasheet says 62 interrupts plus the 16 used by the core, and 78*4 = 312, so the vector table will need 512byte alignment.https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/system-control-block/vector-table-offset-registerQuote(This is particularly annoying if you want to make a dynamic decision on whether you're going to relocated the vector table - acquiring a block of memory with such large alignment "late" in execution is liable to be wasteful...)

author: old gregg
author_rank: Regular Contributor
timestamp: October 26, 2021, 06:25:36 pm
content: QuoteI didn't know there was a bootloader or DFU , the aliexpress seller didn't mention anything. I only saw the the price and the board. Looking for the schematic, I found out about the bootloader. I've no interest in it and the tool provided by the maker are for WIndows, I'm on linux.QuoteI made a full erase of the chip with the STM32CubeProgrammer tool, but still no success even if I write at the very begining of the flash. The same error occurs.

author: ataradov
author_rank: Super Contributor
timestamp: October 26, 2021, 06:38:58 pm
content: In that case bootloader is irrelevant. You need to debug your code. Alternatively you can replace your hard fault handler with the code below, and the value of s_pc will tell you the address of the faulting instruction.Code://-----------------------------------------------------------------------------void irq_handler_hard_fault_c(uint32_t lr, uint32_t msp, uint32_t psp){uint32_t s_r0, s_r1, s_r2, s_r3, s_r12, s_lr, s_pc, s_psr;uint32_t r_CFSR, r_HFSR, r_DFSR, r_AFSR, r_BFAR, r_MMAR;uint32_t *sp = (uint32_t *)((lr & 4) ? psp : msp);s_r0 = sp;s_r1 = sp;s_r2 = sp;s_r3 = sp;s_r12 = sp;s_lr = sp;s_pc = sp;s_psr = sp;r_CFSR = SCB->CFSR; // Configurable Fault Status Register (MMSR, BFSR and UFSR)r_HFSR = SCB->HFSR; // Hard Fault Status Registerr_DFSR = SCB->DFSR; // Debug Fault Status Registerr_MMAR = SCB->MMFAR; // MemManage Fault Address Registerr_BFAR = SCB->BFAR; // Bus Fault Address Registerr_AFSR = SCB->AFSR; // Auxiliary Fault Status Registerasm("nop"); // Setup breakpoint herewhile (1);}//-----------------------------------------------------------------------------__attribute__((naked)) void irq_handler_hard_fault(void) // !!! Rename to match your vector table entry{asm volatile (R"asm(mov r0, lrmrs r1, mspmrs r2, pspb irq_handler_hard_fault_c)asm");}

author: bingo600
author_rank: Super Contributor
timestamp: October 27, 2021, 04:53:22 am
content: They should not be able to mess with the builtin dfu bootloader.Linux:Install dfu-util (must be v 0.9 or higher, else build from source to get latest)Press (stm board9 : Reset + Boot button - Release Reset button (NOT Boot yet)Now the unit should go into DFU loader modeLoad program w. dfu-util.You should be able to follow usb enumeration with ie. :tail -f /var/log/syslogortail -f /var/log/messages/Bingo