2021-12-10 06:20 AM
Hello Everyone.
I'm currently trying to understand how the startup sequence (from power-on to main) of the STMs work.
As I always used the provided tools and files from ST I never had to deal with linker scripts, startup code etc.
This lack of knowledge always bothered me, so I decided to fill this gap.
I thought to make a small project where I don't use any of the ST files and write everything on my own to learn how the startup process actually works.
For this purpose, I created a very basic blinky LED project for a Nucleo-F072RB board, tested it with the common toolchain (CubeIDE and STM scripts & files) to make sure that the code is correct and then create the whole startup sequence on my own with the help of some online tutorials on this matter.
As I'm not familiar with assembly language I unfortunately couldn't take the ST files as a base (and because they are much more advanced as I want them to be for the start)
My toolchain is as follows:
Compiler: ARM (arm-none-eabi-gcc)
Build Utility: GNU Make
Programmer: CubeProgrammer
As the title of my question already suggests I was not able to get it working and therefore seeking your help.
I created a very basic makefile, a startup code where I set up the memory sections and provide the vector table, as well as a simple linker script. For the main code I created a small device header where I simply copied the necessary register defines from the official stm32f072xx.h.
The compilation works without issues and the map file also looks ok. I can see that the vector table is set up in the correct memory region (at least as far as my understanding goes).
But after looking at the GPIO registers I manipulate in my code, I can see that they are unchanged and therefore my code was not executed at all.
Because I have no experience with this, I don't have much ideas about what could cause the problem. But it seems that there is most probably still something wrong with the linker script or startup code.
So it would be much appreciated if someone could have a look at my files and help me finding the problem and get a better understanding of the whole process.
Thank you in advance
Best regards
Flo
2021-12-10 06:31 AM
The debugger should have an option 'run to main()" which can be unchecked and you can step code in from Reset_Handler entry point.
I'll look over the code later.
2021-12-10 07:18 AM
Start a debug session, then pause it, then hit the reset button. That will reset execution back to the start of Reset_Handler, from which you can step through and see where things go wrong.
2021-12-10 07:57 AM
IMO disasm looks good. As others said, single-step in disasm from the reset entry point, and observe.
JW
2021-12-11 02:53 AM
Hello everyone,
Thank you for your answers.
As I didn't use any ST tools for my project I had some trouble setting up the CubeIDE for debugging purpose as I don't have a project but only an .elf file.
I got a bunch of error messages but the debugger perspective opened anyway. Unfortunately only in the disassembly perspective which I can not really read...
I attached the content of this view.
First thing I noticed is, that after pressing the reset button the code jumped right into address 0x080001f0 which is the WWDG_Handler. After pressing "step into" it jumps to address 0x080000c0 which is a line in the main function and then back to 0x080001f0.
As I didn't activate the watchdog and also checked the WDGA bit which is set to 0 (inactive) with the CubeProgrammer register view, I'm wondering if this is a watchdog related problem or if there is something wrong with the vector table/ startup code?
Furthermore I got a lot of errors above the address 0x08000000 and undefined areas inside the WWDG_Handler and further below, but I don't really know why...
If you have a better tool that just needs the .elf file for debugging please let me know.
Thank you for your help,
Best regards
Flo
2021-12-11 09:07 AM
You have redirected all interrupts to one single ISR, so you cannot distinguish which interrupt it was. Either write individual ISRs, or when in the ISR, read out SCB->ICSR ( 0xE000ED04), the bottommost 10 bits (VECTACTIVE) field show the current interrupt's number - post it.
Do you use the built-in bootloader?
What is SP's content?
How are Option Bytes set?
JW
2021-12-12 04:08 AM
Hi,
The CubeProgrammer says there is 0x03 set for the VECTACTIVE field. In the reference manual I cannot find any information regarding this register...
SP points to address 0x20004000 (located at 0x08000000). I cannot access this address with the CubeProgrammer so I don't know the content.
I thought by don't utilizing anything except of the CubeProgrammer I don't use the build-in bootloader? Can I verify this somehow? I see no settings in the tool for this.
Option Bytes are also unchanged from default:
RDP: AA
User Configuration: All checked
Data0: Value 0xFF, Address 0xFF
Data1: Value 0xFF, Address 0xFF
Write Protection: All checked
Here some screenshots:
2021-12-12 04:30 AM
> In the reference manual I cannot find any information regarding this register...
That's because it's register of the processor core, and that's documented in the so called Programming Manual, for Cortex-M0 in PM0215.
3 appears to be HardFault. Now the problem is, that you apparently look at the registers (namely SP) while in reset state, so that won't give much information on that.
I don't think CubeProgrammer is the best way to gain insight into the mcu. You've appeared to have get CubeIDE working, sort of, so try to stick to that one, and look at the content of stack (where SP points) after running the code. Or try to single-step instruction-by-instruction, perhaps in the disasm window (I don't use CubeIDE so I don't know how exactly that works) and observe where does it go and how the registers are changing.
JW
2021-12-14 02:57 AM
Hi and thanks for the answer.
I tried out a lot of stuff but I was not able to get the debugging running so I can single step through...
I don't know where the problem is but it starts, jumps into the WWDG_Handler (or most likely hardfault) and then the whole debugger crashes.
I even tried openocd in the terminal but I don't know how to get it to single step execution. I can flash my program, halt, resume and reset my program but I have no insight into the registers...
The only thing that could be of any value is, that I cannot access addresses above 0x20003FF0 in the CubeProgrammer and get an error if I try to. As the stack pointer should be at 0x20004000 maybe this causes the hardfault?
But if so, why is the border this address? RAM size should be 16k and end of ram therefore at 0x20004000 not 0x20003FF0.
If there is some suitable debugging tool that could help right now, please let me know. I have no clue where the problem could be and I have nearly to none experience of debugging without the IDE and all prepared files (thats why I tried this project to get a better understanding...)
Thank you in advance
2021-12-14 03:12 AM
I just verified with the working cube project, the address 0x20004000 seems to be correct, ST sets the same address at 0x08000000.
Also I got the OpenOCD back up but only find information about current position:
target halted due to debug-request, current mode: Thread
xPSR: 0xc1000000 pc: 0x08000124 msp: 0x20004000
(gdb) step 100
halted: PC: 0x08000126
halted: PC: 0x08000128
halted: PC: 0x0800012a
halted: PC: 0x0800012c
halted: PC: 0x0800012e
halted: PC: 0x08000130
halted: PC: 0x08000132
halted: PC: 0x08000134
halted: PC: 0x08000136
halted: PC: 0x08000138
halted: PC: 0x0800013a
halted: PC: 0x0800013c
halted: PC: 0x0800013e
halted: PC: 0x08000156
halted: PC: 0x08000158
halted: PC: 0x0800015a
halted: PC: 0x0800015c
halted: PC: 0x0800015e
halted: PC: 0x08000160
halted: PC: 0x08000162
halted: PC: 0x08000164
halted: PC: 0x08000166
halted: PC: 0x08000168
halted: PC: 0x0800016a
halted: PC: 0x0800016c
halted: PC: 0x0800016e
halted: PC: 0x08000180
halted: PC: 0x08000182
halted: PC: 0x08000184
halted: PC: 0x08000186
halted: PC: 0x08000188
halted: PC: 0x080000c0
halted: PC: 0x080000c2
halted: PC: 0x080000c4
halted: PC: 0x080000c6
halted: PC: 0x080001a8
halted: PC: 0x080001aa
halted: PC: 0x080001ac
halted: PC: 0x080001ae
halted: PC: 0x080001b0
halted: PC: 0x080001b2
halted: PC: 0x080000c6
halted: PC: 0x080001a8
halted: PC: 0x080001aa
halted: PC: 0x080001ac
halted: PC: 0x080001ae
halted: PC: 0x080001b0
halted: PC: 0x080001b2
halted: PC: 0x080000c6
halted: PC: 0x080001a8
After the first 0x080000c6, the program loops through until the next 0x080000c6...
Does this help in combination with the disassembly?