On the 9fans mailing list, I said I would write something about using the Inferno Thumb compiler to write bare metal code.
I'm also trying to add support for floating point instructions to the compiler so that cores that support FPv4-SP instructions can use them. My branch is being pushed to repositories on BitBucket and GitLab.
The assembler, compiler and linker for Thumb are 5a, tc and tl. These are not built by default when hosted Inferno is built. It should be possible to just enter each of thosee directories in util and run mk.
For the STM32F405 MCU I'm using, I need to build code that loads at an address of 0x08000000 and ensure that data is located at 0x20000000. This means that the mkfile that builds the code must call the tl linker with -T0x08000000 for the text, -D0x20000000 for the data and -R0 to allow the data to be positioned separately to the code.
As with all bare metal coding, a loader is needed to set up the registers and data for the C code. This needs to set the stack pointer and static base registers. It also copies the data from the end of the text section into the data section.
#include "thumb2.h" #include "vectors.s" THUMB=4 STACK_TOP=0x20020000 TEXT _start(SB), THUMB, $-4 MOVW $setR12(SB), R1 MOVW R1, R12 /* static base (SB) */ MOVW $STACK_TOP, R1 MOVW R1, SP /* Copy initial values of data from after the end of the text section to the beginning of the data section. */ MOVW $etext(SB), R1 MOVW $bdata(SB), R2 MOVW $edata(SB), R3 _start_loop: CMP R3, R2 /* Note the reversal of the operands */ BGE _end_start_loop MOVW (R1), R4 MOVW R4, (R2) ADD $4, R1 ADD $4, R2 B _start_loop _end_start_loop: B ,main(SB)
In the main function, I call other functions for setting up clocks, GPIOs and the USART. This is currently in a separate repository for bare metal tests which I'll push to GitLab soon.