rss feed
Search Qries

Embedded Ada Journey 002 - First flashing

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:

   [Ada]          blinky.adb
   [Ada]          last_chance_handler.adb
   [gprbind]      blinky.bexch
   [Ada]          blinky.ali
   [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 on blinky
-rwxr-xr-x 1 dnl dnl 966252 05.02.2018 15:58 blinky*


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.

    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 to 0x080FFFFFF (1 Mbyte).
  • ITCM: from 0x00200000 to 0x002FFFFFF (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

Comments powered by Talkyard.

Share it!
Similar Posts