2020-02-17 07:27 AM
First I want to say that I am a newbie in this field. I am trying to upload and debug a code on a custom-made board based on STM32F303CB chip through a NUCLEO-F446RE board. I am using Eclipse IDE (2019-12), a GNU toolchain and a SEGGER J-Link debugging software.
The code builds successfully with no errors, anyway when starting to debug, a HardFault_handler is called. The code was not written by me. I doubt that the problem is in the code itself (it builds) and rather think that some setting of the tools is not right (correct me if I am wrong). I also tried the same procedure on several boards, so I would exclude a hardware issue as well.
The debugger hangs when initializing the USB in the function **MX_USB_Init()**, leading to a HardFault_handler. When debugging in single-step mode, most funcitons within MX_USB_init() execute successfully, except **USBD_Start(&hUsbDeviceFS)**. When stepping into USBD_Start(...), it arrives in the while(1) loop of the HardFault_handler.
When debugging in resume mode (no single step), debugger would also hang at previous functions which work properly in single-step mode such as **HAL_PCD_Init(&hpcd_USB_FS)**, **HAL_PCDEx_PMAConfig**, **USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC)**, **USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS)** and again **USBD_Start(&hUsbDeviceFS)**.
I commented out the empty Hardfault_Handler() function in stm32f3xx_it.c generated by CubeMX and caused the calling of the default CMSIS Hardfault_Handler() function in exception_handlers.c. Doing that in the debug console I get the values of several registers:
SEGGER J-Link GDB Server V6.60f - Terminal output channel
[HardFault]
Stack frame:
R0 = 00000000
R1 = 0000BF00
R2 = 40005C00
R3 = 00000001
R12 = 0000E000
LR = FFFFFFF9
PC = F3EF8008
PSR = 6000005B
FSR/FAR:
CFSR = 00000001
HFSR = 40000000
DFSR = 00000000
AFSR = 00000000
Misc
LR/EXC_RETURN= FFFFFFF1
Connection closed by the GDB server.
Then in the book "Mastering STM32" I read about the following meanings of the above register values:
LR = FFFF FFF9 - CPU has been running "regular code" (CPU was in thread mode) when the Hard Fault exception was called. It was not an interrupt. The stack used was MSP, FPU Unit disabled.
HFSR = 4000 0000 - the VECTBL bit is set which indicates that the Hard Fault is caused by **failed vector table fetch**. The explanation is as follows:
"Bus error received during a vector table fetch. This happens because the vector table is invalid (the most of the times we forgot to include the assembly file provided by ST or we forgot to modify its extension from lower .s to capital .S)."
In my project there is no .s or .S file and no function is referring to such a file. This makes me think that maybe the programmer is trying to write to a wrong address in the memory because there is no proper startup file. Does that make sense for you? Any help would be appreciated.
Thanks in advance!
Solved! Go to Solution.
2020-02-28 01:33 AM
SOLUTION:
It appeared that really the startup_stm32fXXXxX.S file was missing. I solved the problem by creating a new dummy project for my MCU using CubeMX and generating the code for Other IDEs (GPDSC). Then I copied the generated .s file (in my case startup_stm32f303xc.s) to the system->src->cmsis folder of the original project and deleted the files system_DEVICE.c and vectors_DEVICE.c. I changed the file extension from small .s to capital .S, compiled the project and then I was able to flash and debug the microcontroller successfully.
Thank you!
2020-02-17 09:02 AM
Maybe you try to run your code from RAM and don't copy the vector table properly, or you use some kind of a bootloader and again don't change VTOR properly.
Check the location of the vector table in disasm, and in debugger check value of SCB->VTOR.
JW
2020-02-18 05:39 AM
Hi Jan,
not sure if I'm doing the right thing but here are the results:
SCB->VTOR is being updated twice:
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
Where FLASH_BASE is 0x08000000 and VECT_TAB_OFFSET is 0x0. Here is the disassembly:
203 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
0000135a: mov.w r2, #134217728 ; 0x8000000
0000135e: ldr r3, [pc, #16] ; (0x1370 <SystemInit+88>)
00001360: str r2, [r3, #8]
00001362: bx lr
00001364: asrs r0, r0, #32
00001366: ands r2, r0
00001368: stmia r0!, {r2, r3}
0000136a: ldr??.w pc, [pc, #-3276] ; 0x6a0 <ADPD105_setLedCurrent+184>
0000136e: vpadd.f32 d14, d0, d0
00001372: b.n 0x1376 <SystemCoreClockUpdate+2>
After this operation the value of SCB->VTOR is 0x08000000.
SCB->VTOR = (uint32_t)(&__vectors_start);
The value of __vectors_start ist 0x2000a000 and apparently the &__vectors_start is 0x0 because SCB->VTOR becomes 0 after this iteration. Here is the disassembly:
65 SCB->VTOR = (uint32_t)(&__vectors_start);
000003ba: ldr r3, [pc, #8] ; (0x3c4 <__initialize_hardware_early+16>)
000003bc: ldr r2, [pc, #8] ; (0x3c8 <__initialize_hardware_early+20>)
000003be: str r2, [r3, #8]
000003c0: pop {r3, pc}
000003c2: nop
000003c4: stc 0, cr14, [r0, #-0]
000003c8: movs r0, r0
000003ca: movs r0, r0
Is this what you mean?
SV
2020-02-18 12:52 PM
I meant, look into disasm to find out where the vector table actually is - I don't doubt a simple C line which assigns a value to a register would translate into anything unexpected... (But yes, finding the table alone does not mean there is no code which would copy it into RAM somewhere.)
> _initialize_hardware.c:
> &__vectors_start is 0x0 because SCB->VTOR becomes 0 after this iteration
This is unusual and probably points towards the problem. Find out, what is the purpose of that pointer in that file - I'd guess it's part of some framework, maybe a company framework? There surely must be some documentation accompanying it, if not, well then it's up to you to hack out its purpose and how its value is supposed to be filled in.
JW
2020-02-20 03:05 AM
Hi JW,
as I couldn't find what disasm exactly you refer to, I used a tool called readelf to show the .elf file disassembly. Here are the lines that are related to __vectors_start and __vector_start__:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .isr_vector PROGBITS 00000000 010000 00028c 00 AX 0 0 4
...
Symbol table '.symtab' contains 931 entries:
...
622: 00000000 0 NOTYPE GLOBAL DEFAULT ABS __vectors_start__
...
809: 00000000 0 NOTYPE GLOBAL DEFAULT ABS __vectors_start
Actually __vector_start and __vector_start__ are defined in the linker script (sections.ld):
SECTIONS
{
/*
* For Cortex-M devices, the beginning of the startup code is stored in
* the .isr_vector section, which goes to FLASH.
*/
.isr_vector : ALIGN(4)
{
FILL(0xFF)
__vectors_start = ABSOLUTE(.) ;
__vectors_start__ = ABSOLUTE(.) ; /* STM specific definition */
KEEP(*(.isr_vector)) /* Interrupt vectors */
KEEP(*(.cfmconfig)) /* Freescale configuration words */
/*
* This section is here for convenience, to store the
* startup code at the beginning of the flash area, hoping that
* this will increase the readability of the listing.
*/
*(.after_vectors .after_vectors.*) /* Startup code and ISR */
} >FLASH
And here are the lines in the .map file related to them:
0x00000000 __vectors_start = ABSOLUTE (.)
0x00000000 __vectors_start__ = ABSOLUTE (.)
*(.isr_vector)
.isr_vector 0x00000000 0x44 ./system/src/cmsis/vectors_DEVICE.o
0x00000000 __isr_vectors
As the project was created with an older version of Eclipse and the GNU ARM toolchain and used to work, could it be possible that the issue is due to the newer versions, libraries etc.?
2020-02-28 01:33 AM
SOLUTION:
It appeared that really the startup_stm32fXXXxX.S file was missing. I solved the problem by creating a new dummy project for my MCU using CubeMX and generating the code for Other IDEs (GPDSC). Then I copied the generated .s file (in my case startup_stm32f303xc.s) to the system->src->cmsis folder of the original project and deleted the files system_DEVICE.c and vectors_DEVICE.c. I changed the file extension from small .s to capital .S, compiled the project and then I was able to flash and debug the microcontroller successfully.
Thank you!
2020-02-28 04:30 AM
Thanks for coming back with the solution.
Please chose your post as Best, so that the thread is marked as solved.
JW