cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with self-made startup sequence, code will not execute but map file looks ok

Flo
Associate II

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

11 REPLIES 11

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.

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

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.

If you feel a post has answered your question, please click "Accept as Solution".

IMO disasm looks good. As others said, single-step in disasm from the reset entry point, and observe.

JW

Flo
Associate II

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

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

Flo
Associate II

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:

0693W00000HoIlDQAV.jpg0693W00000HoIlXQAV.jpg0693W00000HoIlcQAF.jpg 

0693W00000HoIlhQAF.jpg0693W00000HoIlmQAF.jpg

> 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

Flo
Associate II

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

Flo
Associate II

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?