Booting A Cortex M with NO IDE : like a caveman : Part 4 Compile,Link and Flash
So here we are at the end of this series now we get to put all the ones and zeros into the chip.
Compiling the main.c and myStartUp.c is straight forward. I will compile them separately and link it all in separate steps and that the end show the single command to do it all in one shot.
First lets make main.c have some thing to do, doesn't matter what it does.
Assuming you have openocd and ATM GNU tools on your system path per the Part 1 of the post.
The command is : arm-none-eabi-gcc -g -c -mthumb -mcpu=cortex-m0plus -std=gnu11 ./src/main.c -o ./outputs/main.o
- arm-none-eabi-gcc: The GCC compiler for ARM Cortex-M processors (no OS or standard libraries).
- -g: Includes debugging information in the compiled output for debugging tools. Generally removed for release firmware, otherwise present so your able to debug properly.
- -c: Compiles the source code into an object file (.o), without linking.
- -mthumb: Compiles the code in Thumb instruction set mode, optimized for ARM's reduced instruction set.
- -mcpu=cortex-m0plus: Specifies the target CPU architecture as Cortex-M0+. This will be specific to your MCU, see the GCC manual -mcpu or -march
- -std=gnu11: Sets the C standard to GNU C11, which is the C11 standard with GNU extensions. Some of you may still like C99, take your pick.
- ./src/main.c: Path to the source file to compile.
- -o ./outputs/main.o: Specifies the output file for the compiled object code (main.o).
We will do the exact same for myStartUp.c
The command is : arm-none-eabi-gcc -g -c -mthumb -mcpu=cortex-m0plus -std=gnu11 myStartUp.c -o ./outputs/myStartUp.o
Next we will link the object files like so: arm-none-eabi-gcc -g -nostdlib -T myLinkerScript.ld outputs/*.o -o outputs/boot.elf -Wl,-Map=outputs/boot.map
- arm-none-eabi-gcc: GCC compiler for ARM Cortex-M processors (bare-metal, no OS).
- -g: Includes debugging information in the output.
- -nostdlib: Prevents linking with the standard C library, useful for embedded systems.
- -T myLinkerScript.ld: Specifies the custom linker script to control memory layout and sections.
- outputs/*.o: Specifies the object files (.o) to be linked. Here we use a wild card (*) to tell it to grab all .o files in that directory
- -o outputs/boot.elf: Specifies the output file as the ELF executable (you can name it whatever you want).
- -Wl,-Map=boot.map: Instructs the linker to generate a memory map file (boot.map) for debugging purposes. This is use full to verify our linker script sections and their content.
Now lets analyze that map file and see where everything ended up.
dummy1 ended up in the data section rightfully so, we can also see our symbols declared in the linker scripts are being resolved.
Out uninitialized variables are in the .bss section.
Constants in the .rodata section.
We can see above our vector table which is supposed to start at 0x00000000 actually starts at 0x08000000 but we talked about why that is. Everything looks great. Now lets flash the device.
The following commands assume you have openocd, scripts, and arm gnu tools on path/ environment variables.
Start openocd with the following command (tailored to match your chip of course):
openocd -f interface/stlink.cfg -f target/stm32g0x.cfg
As you can see there is a local port listening at 3333
So we open up arm gdb and connect to that port, preferably just at the outputs directory when you do this:
the command is :
arm-none-eabi-gdb
Once ARM gdb is open run the following command to connect to localhost.
target remote localhost:3333
The GDB command to actually flash the device are as follow in this order:
- file boot.elf
- load
You can now set a break point at main and set through the code with these commands
- b main (set the break point)
- layoutr src (this command only works on linux)
- c (continue/start running code)
- n (n or s will go to next line, or step to next line)
And there you have it , you have booted the Cortex M core with no IDE or no magic being done for you in the background, aside form compiling, linking etc.
I plan a making a post on some useful GDB debugging features in conjunction with VSCode.
My next post that is not part of this "Booting up" series, but it will be on build systems, I will use the same project as a starting base.
Comments