Blue Pill - Compilation / chargement

Table des matières

TL;DR

Installation des fichiers nécessaires à la compilation depuis un système FreeBSD.

Pré-requis

Avant de compiler du code, il faut récupérer (et adapter) quelques fichiers mis à disposition par ST. Un Makefile est disponible:
$ git clone https://gitlab.com/dsx/blue-pill.git
$ cd blue-pill/stm32f103c8t6/00_gpio
$ make stm32-base
$ make stm32-cube
Attention à bien lancer les cibles stm32-base et stm32-cube depuis un sous-répertoire de stm32f103c8t6 . Chaque cible va récupérer une archive depuis https://github.com/STM32-base et en extraire le strict minimum à la racine du projet:
$ make stm32-base
fetch -o /tmp/stm32-base.zip https://github.com/STM32-base/STM32-base/archive/refs/heads/master.zip
fetch: https://github.com/STM32-base/STM32-base/archive/refs/heads/master.zip: size of remote file is not known
/tmp/stm32-base.zip                                    219 kB 4322 kBps    00s
tar xf /tmp/stm32-base.zip -C ../.. STM32-base-master/linker STM32-base-master/startup
rm /tmp/stm32-base.zip
sed -i .orig -e 's/_user_heap_stack :/_user_heap_stack (NOLOAD) :/' ../../STM32-base-master/linker/common.ld
sed -i .orig -e '/Call the system init function/,/__libc_init_array/d' ../../STM32-base-master/startup/startup_common.s

$ make stm32-cube
fetch -o /tmp/stm32-cube.zip https://github.com/STM32-base/STM32-base-STM32Cube/archive/refs/heads/master.zip
fetch: https://github.com/STM32-base/STM32-base-STM32Cube/archive/refs/heads/master.zip: size of remote file is not known
/tmp/stm32-cube.zip                                     32 MB 4907 kBps    07s
tar xf /tmp/stm32-cube.zip -C ../.. STM32-base-STM32Cube-master/CMSIS
rm /tmp/stm32-cube.zip
L'arborescence obtenue est la suivante:
d FreeBSD
d STM32-base-master
d   linker
d   startup
d STM32-base-STM32Cube-master
d stm32f103c8t6
  f Makefile.stm32f103c8t6
  f openocd.cfg
  d 00_gpio
    f Makefile
    f main.c
  d 00_gpio_systick
  d ...
Les sous-répertoires de STM32-base-master contiennent les fichiers nécessaires à l'édition des liens et à la gestion des interruptions et ce pour plusieurs modèles de carte. C'est dans le répertoire STM32-base-STM32Cube-master qu'on trouve le Common Microcontroller Software Interface Standard qui fournit 3 principaux fichiers:

Compilation / chargement

On remarquera qu'il n'est nul besoin d'installer arm-none-eabi-gcc car la chaine de compilation fournie par FreeBSD a le bon goût de ne pas se limiter à l'architecture de l'hôte:
$ cc -print-targets
  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_32 - AArch64 (little endian ILP32)
    aarch64_be - AArch64 (big endian)
    arm        - ARM
    arm64      - ARM64 (little endian)
    arm64_32   - ARM64 (little endian ILP32)
    armeb      - ARM (big endian)
    mips       - MIPS (32-bit big endian)
    mips64     - MIPS (64-bit big endian)
    mips64el   - MIPS (64-bit little endian)
    mipsel     - MIPS (32-bit little endian)
    ppc32      - PowerPC 32
    ppc32le    - PowerPC 32 LE
    ppc64      - PowerPC 64
    ppc64le    - PowerPC 64 LE
    riscv32    - 32-bit RISC-V
    riscv64    - 64-bit RISC-V
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64
Pour charger la carte, j'utilise un adaptateur st-link v2 et le "package" devel/openocd:
$ cd blue-pill/FreeBSD
$ doas cp devd/st-link_v2.conf /usr/local/etc/devd
$ doas service devd restart
$ doas pkg install openocd
Une fois la Blue Pill et l'adaptateur connecté (rechercher "st-link v2 connect blue pill"), on peut lancer la commande suivante DANS UN AUTRE TERMINAL:
$ cd blue-pill/stm32f103c8t6
$ openocd -f openocd.cfg -c "init"
Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 1000 kHz
Info : STLINK V2J29S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.273887
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : gdb port disabled
Info : tcl server disabled
Info : Listening on port 4444 for telnet connections
Depuis un sous-répertoire on peut compiler et charger la carte:
$ cd blue-pill/stm32f103c8t6/00_gpio
$ make build
rm -f main.o startup.o system.o main.elf main.bin
cc  --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -DSTM32F103xB -I /usr/include -I ../../STM32-base-STM32Cube-master/CMSIS/STM32F1xx/inc -I ../../STM32-base-STM32Cube-master/CMSIS/ARM/inc -Wno-unused-command-line-argument -c main.c -o main.o
cc --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -DSTM32F103xB -I /usr/include -I ../../STM32-base-STM32Cube-master/CMSIS/STM32F1xx/inc -I ../../STM32-base-STM32Cube-master/CMSIS/ARM/inc -Wno-unused-command-line-argument -I ../../STM32-base-master/startup -c ../../STM32-base-master/startup/STM32F1xx/STM32F103xB.s -o startup.o
../../STM32-base-master/startup/startup_common.s:24:1: warning: Reset_Handler changed binding to STB_WEAK
.weak Reset_Handler
^
cc --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -DSTM32F103xB -I /usr/include -I ../../STM32-base-STM32Cube-master/CMSIS/STM32F1xx/inc -I ../../STM32-base-STM32Cube-master/CMSIS/ARM/inc -Wno-unused-command-line-argument -c ../../STM32-base-STM32Cube-master/CMSIS/STM32F1xx/src/system_stm32f1xx.c -o system.o
ld.lld -nostdlib --no-rosegment -z nognustack -L ../../STM32-base-master/linker -T ../../STM32-base-master/linker/STM32F1xx/STM32F103xB.ld -o main.elf main.o startup.o system.o
llvm-objcopy -O binary main.elf main.bin
   text    data     bss     dec     hex filename
    840       4    1536    2380     94c main.elf
$ make reset
Open On-Chip Debugger
> reset halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x080006f0 msp: 0x20005000
> Open On-Chip Debugger
> flash write_image erase main.bin 0x8000000
device id = 0x20036410
flash size = 25616kbytes
auto erase enabled
wrote 2048 bytes from file main.bin in 0.115174s (17.365 KiB/s)

> Open On-Chip Debugger
> reset run
Désolé pour les afficionados valencians de gdb, il a beau être l'outil de référence pour charger et déverminer du code je n'en ai pas encore eu besoin (d'où sa désactivation dans openocd.cfg).