cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L412 hardfault while using minimal CubeIDE example.

RKnoe
Associate II

I try to set up an USB CDC project for a STM32L412KB Nucleo32 board using CubeIDE.

I activated the USB connection and the USB middleware with the default USB CDC setup.

If I run this code, it ends in the hardfault handler with INVSTATE raised during the USB_EnableGlobalInt(hpcd) call (HAL_PCD_Start() at stm32l4xx_hal_pcd.c:1,014 0x8000d26).

The next items on the call stacks are: <signal handler called>() at 0xfffffff9, 0x0, <signal handler called>() at 0xfffffff1   and finally HardFault_Handler() at stm32l4xx_it.c:88 0x800432a.

Currently I ran out of ideas on what to do. USB CDC worked in projects set up for the STM32F072 and F103 - should we change from the L4 to another MCU?

20 REPLIES 20

0690X000009YwiyQAC.png

(picture courtesy of @SToma​ )

lizerd
Associate III

hi all.

thanks for the hint Jan, but when I do singel step, it works fine until I push resume.

So I can single step trough the whole thing and it is fine, but when I let the processor run freely again it ends up in HardFault.

So I am not any wiser from that unfortunately.

I have really been trying to figure this out, and solve how to implement clive's HardFault data.

What I can not figure out is how to make the compiler/MCU the added HardFualt addition in startup.s

Because I use Truestudio the code sample for the assembly code did not work,

So I found a example on https://nathan.vertile.com/blog/2016/05/04/stm32-hardfault-debugging/

/**
 * My code in startup_stm32l412xx.s
 *
*/
	.section  .text.Reset_Handler
	.weak  HardFault_Handler
	.type  HardFault_Handler, %function
HardFault_Handler:
  movs r0,#4
  movs r1, lr
  tst r0, r1
  beq _MSP
  mrs r0, psp
  b _HALT
_MSP:
  mrs r0, msp
_HALT:
  ldr r1,[r0,#20]
  b hard_fault_handler_c
  bkpt #0
 
.size  HardFault_Handler, .-HardFault_Handler
// My code in stm32l4xx_it.c
 
void hard_fault_handler_c(unsigned long *hardfault_args)
{
  volatile unsigned long stacked_r0 ;
  volatile unsigned long stacked_r1 ;
  volatile unsigned long stacked_r2 ;
  volatile unsigned long stacked_r3 ;
  volatile unsigned long stacked_r12 ;
  volatile unsigned long stacked_lr ;
  volatile unsigned long stacked_pc ;
  volatile unsigned long stacked_psr ;
  volatile unsigned long _CFSR ;
  volatile unsigned long _HFSR ;
  volatile unsigned long _DFSR ;
  volatile unsigned long _AFSR ;
  volatile unsigned long _BFAR ;
  volatile unsigned long _MMAR ;
 
  stacked_r0 = ((unsigned long)hardfault_args[0]) ;
  stacked_r1 = ((unsigned long)hardfault_args[1]) ;
  stacked_r2 = ((unsigned long)hardfault_args[2]) ;
  stacked_r3 = ((unsigned long)hardfault_args[3]) ;
  stacked_r12 = ((unsigned long)hardfault_args[4]) ;
  stacked_lr = ((unsigned long)hardfault_args[5]) ;
  stacked_pc = ((unsigned long)hardfault_args[6]) ;
  stacked_psr = ((unsigned long)hardfault_args[7]) ;
 
  // Configurable Fault Status Register
  // Consists of MMSR, BFSR and UFSR
  _CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;
 
  // Hard Fault Status Register
  _HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
 
  // Debug Fault Status Register
  _DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;
 
  // Auxiliary Fault Status Register
  _AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;
 
  // Read the Fault Address Registers. These may not contain valid values.
  // Check BFARVALID/MMARVALID to see if they are valid values
  // MemManage Fault Address Register
  _MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
  // Bus Fault Address Register
  _BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
 
  __asm("BKPT #0\n") ; // Break into the debugger
}

but this do not work, ??

what I found in Truestudio was the problem window.

0690X000009Yx88QAC.png

It reports an hard fault and gives some info, unfortunately I do not understand what it means.

The wired thing is, I downloaded the tryout of Crossworks and it works with the board if I create an MDK-ARM V5 project in CubeMX and import it into crossworks and just run. It works. So there is no problem with the MCU or the board.

:see_no_evil_monkey:

Remove the WEAK settings in startup.s and comment out whatever is currently in stm32fxyz_it.c ?

I think I've posted GNU/GCC syntax code previously, blindly this should suffice..

..
                TST     lr, #4          /* Determine correct stack */
                ITE     EQ
                MRSEQ   R0, MSP         /* Read MSP (Main) */
                MRSNE   R0, PSP         /* Read PSP (Process) */
 
                MOV     R1, R4          /* Registers R4-R6 */
                MOV     R2, R5
                MOV     R3, R6          /* sourcer32@gmail.com */
 
                B       hard_fault_handler_c
 

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

> thanks for the hint Jan, but when I do singel step, it works fine until I push resume.

> So I can single step trough the whole thing and it is fine, but when I let the processor run freely again it ends up in HardFault.

My guess is, that the problem occurs in the USB interrupt service routine (ISR), and you have disabled interrupts during single-step (that's a common setting, otherwise it would be hard to single-step most practical programs).

You may perhaps want to place a breakpoint into the USB ISR and single-step from there to see, where that will take you.

Do you have a PC connected to the USB when the problem occurs?

JW

Should check for malloc()/free() idiocy that they like to do in interrupt context

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

Yes. For me the reason was a forgotten ISR definition in the Startup/startup_stm32l412kbux.s file. It should contain:

   .word   0

   .word   COMP_IRQHandler

   .word   LPTIM1_IRQHandler

   .word   LPTIM2_IRQHandler

   .word   USB_IRQHandler

   .word   DMA2_Channel6_IRQHandler

   .word   DMA2_Channel7_IRQHandler

lizerd
Associate III

YESSSSS.

ruediger1.561124119260664E12 Hade the right answer to my problem.

Missing IRQ routine linkage .

@RKnoe​ Thanks

ruediger1.561124119260664E12
 
(Community Member)
2 hours ago
 
Yes. For me the reason was a forgotten ISR definition in the Startup/startup_stm32l412kbux.s file. It should contain:
 
 
 
   .word   0
 
   .word   COMP_IRQHandler
 
   .word   LPTIM1_IRQHandler
 
   .word   LPTIM2_IRQHandler
 
   .word   USB_IRQHandler
 
   .word   DMA2_Channel6_IRQHandler
 
   .word   DMA2_Channel7_IRQHandler

The USB_IRQHandler vector is present in both arm and iar version of startup code, absent only in the gcc version. IMO it's a bug. @Imen DAHMEN​  can you please have a look? Thanks.

JW

Hello All,

This issue is raised internally for fix.

Thanks for your contribution.

Best Regards,

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Note to self, Cortex-M0(+) startup.s code for Keil

HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler
                EXTERN  hard_fault_handler_c
 
                MOV     R1, LR
                LDR     R0, =hard_fault_handler_c
                MOV     LR, R0
                MOVS    R0, #4          ; Determine correct stack
                TST     R0, R1
                MRS     R0, MSP         ; Read MSP (Main)
                BEQ     .+6             ; BEQ 2, MRS R0,PSP 4
                MRS     R0, PSP         ; Read PSP (Process)
 
                MOV     R1, R4          ; Registers R4-R6, as parameters 2-4 of the function called
                MOV     R2, R5
                MOV     R3, R6          ;  sourcer32@gmail.com
 
                BX      LR
                ENDP

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