Embedded Ada Journey 002 - First flashing
February 5, 2018
In the last post I talked about the tools I use to do my development and the board I bought. Today, I will talk about the first toolchain test I did.
First step
You should download the Ada Drivers Library from github.
Then, change to Ada_Drivers_Library/examples/STM32F746_Discovery
directory, in my case is STM32F746. You will find examples for STM32F429, STM32F469, STM32F4, STM32F746, and STM32F769
Cross compiling
- We will generate the machine readable file with
$ gprbuild blinky_f7disco.gpr
What is GPRbuild? From AdaCore documentation. GPRbuild is a generic build tool designed for the construction of large multi-language systems organized into subsystems and libraries. It is well-suited for compiled languages supporting separate compilation, such as Ada, C, C++ and Fortran. More info here.
And it has three phases: Compilation, post-compilation (binding) and linking phase. You will see, after executing gprbuild
, something similar to the following:
Compile
[Ada] blinky.adb
[Ada] last_chance_handler.adb
Bind
[gprbind] blinky.bexch
[Ada] blinky.ali
Link
[link] blinky.adb
Memory region Used Size Region Size %age Used
itcm: 0 GB 16 KB 0.00%
flash: 139420 B 1 MB 13.30%
dtcm: 0 GB 64 KB 0.00%
sram12: 26368 B 240 KB 10.73%
- Change your directory to
Ada_Drivers_Library/examples/shared/hello_world_blinky/obj/stm32f7disco
. In that directory you will find a bunch of files. But for now we will focus onblinky
-rwxr-xr-x 1 dnl dnl 966252 05.02.2018 15:58 blinky*
ELF vs BIN
Before flashing our executable we must convert it to a binary file
$ arm-eabi-objcopy -O binary blinky blinky.bin
The -O
receive a bfdname
as the object format for both the input and the output file. You will find more information in the help page of arm-eabi-objcopy.
The elf files contains a header that give us information that will help the linker to parse and interpret the object file.
I wrote a post some time ago about elf basics.
So why I should convert to binary file? elf files have meta information besides from the code itself, and all that information should be understood by some loader.
Some meta information from the elf file:
$ arm-eabi-readelf -h blinky
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2 s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x801e799
Start of program headers: 52 (bytes into file)
Start of section headers: 965452 (bytes into file)
Flags: 0x5000400, Version5 EABI, hard-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 4
Size of section headers: 40 (bytes)
Number of section headers: 20
In the case of STM32XX, that’s not an option. From the STM32 User Manual UM0892, the only formats that can be used to program the microcontroller are binary, Intel Hex or Motorola S-record. Thus, we use binary because we have the tool to convert straightforward from elf to binary.
ELF vs BIN quick view
We can read part of code from .text
section in the elf file:
$ arm-eabi-objdump -D blinky
blinky: file format elf32-littlearm
Disassembly of section .text:
08000000 <__vectors0>:
8000000: 20016700 andcs r6, r1, r0, lsl #14
8000004: 0801e799 stmdaeq r1, {r0, r3, r4, r7, r8, r9, sl, sp, lr, pc}
8000008: 0801e806 stmdaeq r1, {r1, r2, fp, sp, lr, pc}
Note the starting address 0x08000000
. But now let’s see some part of the bin file,
in just 0’s and 1’s.
$ xxd -b blinky.bin
00000000: 00000000 01100111 00000001 00100000 10011001 11100111
00000006: 00000001 00001000 00000110 11101000 00000001 00001000
0000000c: 00000110 11101000 00000001 00001000 00000110 11101000
And in hexadecimal form
$ xxd blinky.bin
00000000: 0067 0120 99e7 0108 06e8 0108 06e8 0108
00000010: 06e8 0108 b0b5 84b0 00af c820 1df0 78fd
00000020: c7e9 0001 1df0 20fd c7e9 0201 03f0 e2fb
There are two main points to notice:
-
First, the starting address in the bin file
0x00000000
. We will take this into account when we program the microcontroller. -
Second, the information bin file is the same as the one in
.text
, as expected.
00000000:
0067 0120 99e7 0108 06e8 0108 06e8 0108
/* change endianness */
0076 1002 997e 1080 608e 1080 608e 1080
| from BIN file | from ELF file |
----------------------------------
2001 6700 | andcs ...
0801 e799 | stmdaeq ...
0801 e806 | stmdaeq ...
Flashing the code
The last part is to actually program the microcontroller or flash the memory of the microcontroller with the binary code. To do so, we use the st-link
$ st-flash write blinky.bin 0x8000000
st-flash
is to flash binary files to STM32 device, write
is to indicate that we are writing firmware blinky.bin
to device starting from 0x8000000
. Remember where is the .text
section in the elf and the initial address in the bin file?
It is also possible to read the code from the platform, but I won’t show you here.
Another way to know in which address to flash is just reading the documentation. In the case of STM32F745X and STM32F746X, we can flash using two interfaces:
- AXIM: from
0x08000000
to0x080FFFFFF
(1 Mbyte). - ITCM: from
0x00200000
to0x002FFFFFF
(1 Mbyte).
Main difference between these two interfaces is documented (quick ref) and I quote:
- ITCM: Connected to the Cortex-M7 ITCM bus and used for code execution and data read accesses to the Flash memory. Write accesses to the Flash memory are not possible through this interface.
- AXI: The Flash memory remains accessible to the Cortex-M7 processor and other masters such as DMA controllers.
More info about:
- The ARM Advanced Microcontroller Bus Architecture (AMBA) and the Advanced eXtensible Interface (AXI).. wikipedia and official arm documentation
Share it!
Comments powered by Talkyard.