Author Topic: STM32F401 hard fault at boot time  (Read 941 times)

0 Members and 1 Guest are viewing this topic.

Offline old gregg

  • Regular Contributor
  • *
  • Posts: 124
  • Country: fr
STM32F401 hard fault at boot time
« on: October 24, 2021, 06:45:50 pm »
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: [Select]
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_ExtSRAM
  SystemInit_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_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->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 locations

Code: [Select]
Memory Configuration

Name             Origin             Length             Attributes
FLASH            0x0000000008000000 0x0000000000040000 xr
RAM              0x0000000020000000 0x0000000000010000 xrw
MEMORY_B1        0x0000000060000000 0x0000000000000000 xr
CCMRAM           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



 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8227
  • Country: us
    • Personal site
Re: STM32F401 hard fault at boot time
« Reply #1 on: October 24, 2021, 06:54:01 pm »
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 Register
SCB->DFSR;  // Debug Fault Status Register
SCB->MMFAR; // MemManage Fault Address Register
SCB->BFAR;  // Bus Fault Address Register
SCB->AFSR;  // Auxiliary Fault Status Register

Those registers will contain quite a bit of information about the fault.
Alex
 
The following users thanked this post: AndrewBCN

Offline old gregg

  • Regular Contributor
  • *
  • Posts: 124
  • Country: fr
Re: STM32F401 hard fault at boot time
« Reply #2 on: October 24, 2021, 08:07:48 pm »
Hi Ataradov !

here are the register,

CFSR : INVSTATE
HFSR : FORCED
DFSR : VCATCH | HALTED
MMFAR : 0xe000edf8

precise data Violation (PRECISERR)
BFAR : 0x20010000 (is it in RAM ?)

the chip is :
SRAM size : 64KiB
FLASH size : 256KiB
chip id : 00000423
Core id : 2ba01477


« Last Edit: October 24, 2021, 08:15:24 pm by old gregg »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8227
  • Country: us
    • Personal site
Re: STM32F401 hard fault at boot time
« Reply #3 on: October 24, 2021, 08:19:13 pm »
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.
Alex
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8227
  • Country: us
    • Personal site
Re: STM32F401 hard fault at boot time
« Reply #4 on: October 24, 2021, 08:23:42 pm »
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.
Alex
 

Offline emece67

  • Frequent Contributor
  • **
  • Posts: 418
  • Country: es
Re: STM32F401 hard fault at boot time
« Reply #5 on: October 24, 2021, 10:02:51 pm »
INVSTATE means that something tried to jump to a non-thumb code.

The addresses 0xe000edf8 and 0x20010000 are suspicious. Especially the first one. ...

As said, INVSTATE means that somebody tried to switch to non-Thumb mode. This happens if:
  • Instructions BX, BLX or POP {PC} try to put a 0 on the LSB of the PC (such LSB does not land on the PC, but in the T bit of the PSR, thus switching to non-Thumb mode)
  • At a exception return, the PSR restored from the stack does have its T bit at 0
  • The processor fetches a vector from the vector table that has its LSB equal to 0 (have you built the new vector table before loading VTOR?)

Address 0xE000EDF8 may be meaningless, provided that MMFSR[MMARVALID] is 0. In fact, I get the same 0xE000EDF8 when firing the same hardfault (via a BX instruction) on the STM32L432 I'm working now.

Hope this helps, regards.
Information must flow.
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 618
  • Country: ru
Re: STM32F401 hard fault at boot time
« Reply #6 on: October 24, 2021, 10:16:25 pm »
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].
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 8210
  • Country: nz
Re: STM32F401 hard fault at boot time
« Reply #7 on: October 24, 2021, 10:23:26 pm »
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.
Greek letter 'Psi' (not Pounds per Square Inch)
 

Online bson

  • Supporter
  • ****
  • Posts: 2062
  • Country: us
Re: STM32F401 hard fault at boot time
« Reply #8 on: October 25, 2021, 01:10:32 am »
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).
« Last Edit: October 25, 2021, 01:12:50 am by bson »
 

Offline old gregg

  • Regular Contributor
  • *
  • Posts: 124
  • Country: fr
Re: STM32F401 hard fault at boot time
« Reply #9 on: October 25, 2021, 11:19:50 am »
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.  :palm:

https://github.com/WeActTC/MiniSTM32F4x1
« Last Edit: October 25, 2021, 01:33:24 pm by old gregg »
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1657
  • Country: dk
Re: STM32F401 hard fault at boot time
« Reply #10 on: October 25, 2021, 08:36:09 pm »
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
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8227
  • Country: us
    • Personal site
Re: STM32F401 hard fault at boot time
« Reply #11 on: October 25, 2021, 09:14:38 pm »
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.
Alex
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 3567
  • Country: us
Re: STM32F401 hard fault at boot time
« Reply #12 on: October 25, 2021, 11:10:17 pm »
Quote
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.
It'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-register
Quote
When setting TBLOFF, you must align the offset to the number of exception entries in the vector table. The minimum alignment is 32 words, enough for up to 16 interrupts. For more interrupts, adjust the alignment by rounding up to the next power of two. For example, if you require 21 interrupts, the alignment must be on a 64-word boundary because the required table size is 37 words, and the next power of two is 64. See your vendor documentation for the alignment details for your device.
(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...)
 
The following users thanked this post: Tagli

Offline old gregg

  • Regular Contributor
  • *
  • Posts: 124
  • Country: fr
Re: STM32F401 hard fault at boot time
« Reply #13 on: October 26, 2021, 06:25:36 pm »
Quote
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 ?

I 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.

Quote
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.

I 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.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8227
  • Country: us
    • Personal site
Re: STM32F401 hard fault at boot time
« Reply #14 on: October 26, 2021, 06:38:58 pm »
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: [Select]
//-----------------------------------------------------------------------------
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[0];
  s_r1  = sp[1];
  s_r2  = sp[2];
  s_r3  = sp[3];
  s_r12 = sp[4];
  s_lr  = sp[5];
  s_pc  = sp[6];
  s_psr = sp[7];
 
  r_CFSR = SCB->CFSR;  // Configurable Fault Status Register (MMSR, BFSR and UFSR)
  r_HFSR = SCB->HFSR;  // Hard Fault Status Register
  r_DFSR = SCB->DFSR;  // Debug Fault Status Register
  r_MMAR = SCB->MMFAR; // MemManage Fault Address Register
  r_BFAR = SCB->BFAR;  // Bus Fault Address Register
  r_AFSR = SCB->AFSR;  // Auxiliary Fault Status Register

  asm("nop"); // Setup breakpoint here

  while (1);
}

//-----------------------------------------------------------------------------
__attribute__((naked)) void irq_handler_hard_fault(void) // !!! Rename to match your vector table entry
{
  asm volatile (R"asm(
    mov    r0, lr
    mrs    r1, msp
    mrs    r2, psp
    b      irq_handler_hard_fault_c
    )asm"
  );
}

Alex
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1657
  • Country: dk
Re: STM32F401 hard fault at boot time
« Reply #15 on: October 27, 2021, 04:53:22 am »
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 mode
Load program w. dfu-util.

You should be able to follow usb enumeration with ie. : tail -f /var/log/syslog or tail -f /var/log/messages

/Bingo
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf