This page explains how to use UART to update the boot device (SD card, e•MMC, NOR, NAND) with OpenSTLinux distribution.
1. UART as serial boot device[edit | edit source]
A UART instance can be used as a serial boot device if the selected UART is supported by :
- ROM code, with the PIN configuration
- TF-A device tree, including pincontrol
- U-Boot device tree, including pincontrol
On STM32 MPU STMicrolectronics boards, the UART used for console can be used as UART boot device.
OpenSTLinux distribution doesn't provide the flash memory layout (flashlayout) files required to use a UART as a serial boot device.
Refer to Using_STM32Programmer_over_UART chapter to see how to modify a flashlayout file to use the TF-A BL2 binary with UART support: tf-a-<board>-uart.stm32.
You can use this modified flashlayout as described in STM32CubeProgrammer article.
By default the baudrate used by STM32CubeProgrammer on UART is 115200 bit/s so the operations are very slow.
| the UART serial link is slower than USB, so it is NOT a recommended interface to program big files as a filesystem binaries. But if USB device is not available or not functional, the UART serial boot allows to load in DDR or to program the bootloaders, and use them to program the rest of the system with a faster interface as USB, ethernet... |
Refers to page:
- How_to_manually_update_bootloaders for example of U-Boot commands used to update the memory
- How to load U-Boot with STM32CubeProgrammer for command used to load U-Boot in DDR with STM32CubeProgrammer over UART.
Moreover the default UART baudrate can be increased if a higher UART frequency is supported by the hardware, for example on ST Microelectronics boards and with console on STLink you can increase it up to 1 Mbit/s:
- the selected baudrate is selected on host with the br option of STM32CubeProgrammer
- the UART baudrate is automatically detected by ROM code
- for bootloaders, the baudrate is defined during compilation:
- in your U-Boot board defconfig with the CONFIG_BAUDRATE flags
- for TF-A BL2 with compilation flage STM32MP_UART_BAUDRATE
2. Using serial boot on UART console[edit | edit source]
To use STM33CubeProgrammer on UART serial console, you must:
- Modify the flashlayout tsv file to use the specific fsbl binary dedicated to use UART serial by adapting only the fsbl-boot binary
- Prepare the board by putting the board on programming mode and power-on/reset the board; the red led is blinking
- Launch the process with the tool STM32Programmer and the adapted flashlayout TSV file with UART serial binary
See the last chapter for complete examples.
| If you have adapted OP-TEE and U-Boot to use a different UART serial, you need to adapt also the fip-boot binary |
When UART instance used for serial boot is the same than UART used for the bootloader consoles, useful for debug, these console are automatically deactivated. See the next chapter to debug tips.
STM32CubeProgrammer provides the list of different interfaces available with option -l, including the USB DFU devices present if a USB cable with DFU support is unfortunately connected to the board.
STM32_Programmer_CLI -l
-------------------------------------------------------------------
STM32CubeProgrammer v2.22.0
-------------------------------------------------------------------
===== DFU Interface =====
Total number of available STM32 device in DFU mode: 1
Device Index : USB1
USB Bus Number : 003
USB Address Number : 004
Product ID : DFU in HS Mode @Device ID /0x501, @Revision ID /0x1003
Serial number : 003D000B3232511538303631
Firmware version : 0x0110
Device ID : 0x0501
===== UART Interface =====
Total number of serial ports available: xx
...
Board Name : STM32MP135F-DK
ST-LINK SN: 001200284741500420383733
Port: ttyACM0
Location: /dev/ttyACM0
Description: STLINK-V3
Manufacturer: STMicroelectronics
..
Board Name : STM32MP135F-DK
ST-LINK SN: 001200284741500420383733
Port: ttyACM1
Location: /dev/ttyACM1
Description: STLINK-V3
Manufacturer: STMicroelectronics
..
Port: ttyUSB1
Location: /dev/ttyUSB1
Description: CP2102 USB to UART Bridge Controller
Manufacturer: Silicon Labs
- the UART for console is provided with an embedded ST-LINK on a dedicated USB connector (Type-C or micro-B), available with a ttyACM device on Linux PC
except for STM32MP215F-DK
on which the functionality is available via specific connectors (see STM32MP215x-DKx board overview for details). - for boards with a connector USB Type-C common for Power in and for ST-Link, as STM32MP257F-DK
, the PC must be connected on USB Type-C port with Power Delivery support with USB Type-C/Type-C cable.
3. Debug[edit | edit source]
As the UART console is not available when STM32CubeProgrammer on UART is used, the debug is done with GDB when the only one UART instance is available.
See How to load U-Boot with STM32CubeProgrammer page for tips to restore console in U-Boot when boot-loader are loaded and STM32CubeProgrammer is no more used.
For STMicroelectronics boards, we have only one UART activated by default, used for console and provided by embedded ST-Link for most of STMicroelectronics boards, thus we have no console when STCubeProgrammer is used over this UART on board this console.
3.1. Add a second console[edit | edit source]
If you have a second UART available on your design, you can use it for a debug trace of boot-loaders during a serial UART boot.
In this case, the board use one UART instance of STM32CubeProgrammer and one instance for the console when the seconde UART is configured:
- either use the second UART instance available on the board is supported by ROM code for serial boot;
this UART instance need to be defined in U-Boot and in TF-A device tree to be used bystm32progcommand and the console is kept unchanged in boot-loaders - either activate and select the second UART as console in each boot-loader;
the used console and early console must be identical in TF-A, OP-TEE and U-Boot:- update
stdout-pathin thechosennode of each device tree - when early debug is activated, update build configuration for the used uart instance because early console of each boot-loader assumed that UART configuration is done by previous stage
- for details more debug details, see the debug page of each boot-loaders
- update
3.2. Example of debug console activation[edit | edit source]
As example, on STM32MP157x-EV1 a second UART is available on GPIO extension connector with:
- GND (Black) on pin 6 (GND)
- RXD (Yellow) on pin 8 (USART3_TX)
- TXD (Orange) on pin10 (USART3_RX)
The device tree modification to change the console, when UART is present (here serial1) in device tree but not activated is:
aliases {
serial0 = &uart4;
serial1 = &usart3;
};
// change console to serial1
chosen {
stdout-path = "serial1:115200n8";
};
// activate serial on GPIO connector
&usart3 {
status = "okay";
};
The device tree modification to add a new UART instance, with replace console on serial0 is:
aliases {
- serial0 = &usart2;
+ serial0 = &uart5;
};
chosen {
stdout-path = "serial0:115200n8";
};
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart5_pins_a>;
+ status = "okay";
+};
+
+&pinctrl {
+ uart5_pins_a: uart5-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 9, AF5)>; /* UART5_TX */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('G', 10, AF5)>; /* UART5_RX */
+ bias-disable;
+ };
+ };
+};
4. Examples[edit | edit source]
The next UART flashlayout examples on STM32MP157F-DK2
are based on the initial USB file "flashlayout_st-image-weston/optee/FlashLayout_sdcard_stm32mp157f-dk2-optee.tsv":
#Opt Id Name Type IP Offset Binary - 0x01 fsbl-boot Binary none 0x0 arm-trusted-firmware/tf-a-stm32mp157f-dk2-optee-programmer-usb.stm32 - 0x03 fip-boot FIP none 0x0 fip/fip-stm32mp157f-dk2-optee-programmer-usb.bin P 0x04 fsbl1 Binary mmc0 0x00004400 arm-trusted-firmware/tf-a-stm32mp157f-dk2-optee-sdcard.stm32 P 0x05 fsbl2 Binary mmc0 0x00044400 arm-trusted-firmware/tf-a-stm32mp157f-dk2-optee-sdcard.stm32 PD 0x06 metadata1 FWU_MDATA mmc0 0x00084400 arm-trusted-firmware/metadata.bin PD 0x07 metadata2 FWU_MDATA mmc0 0x000C4400 arm-trusted-firmware/metadata.bin P 0x08 fip-a FIP mmc0 0x00104400 fip/fip-stm32mp157f-dk2-optee-sdcard.bin PED 0x09 fip-b FIP mmc0 0x00504400 none PED 0x0A u-boot-env ENV mmc0 0x00904400 none P 0x10 bootfs System mmc0 0x00984400 st-image-bootfs-openstlinux-weston-stm32mp1.bootfs.ext4 P 0x11 vendorfs FileSystem mmc0 0x04984400 st-image-vendorfs-openstlinux-weston-stm32mp1.vendorfs.ext4 P 0x12 rootfs FileSystem mmc0 0x05984400 st-image-weston-openstlinux-weston-stm32mp1.rootfs.ext4 P 0x13 userfs FileSystem mmc0 0x105984400 st-image-userfs-openstlinux-weston-stm32mp1.userfs.ext4
Used with command:
STM32_Programmer_CLI -c port=usb1 -w FlashLayout_sdcard_stm32mp157f-dk2-optee.tsv
And the used UART port, on Linux is /dev/ttyACM0.
4.1. Load bootloaders in DDR[edit | edit source]
With default UART baudrate at 115200 bits/s, the U-Boot take up to 4 minutes for complete.
See page How_to_load_U-Boot_with_STM32CubeProgrammer for detail and the need changes in U-Boot to have console access.
In the flashlayout file, "tf-a-stm32mp157f-dk2-optee-programmer-usb.stm32" is replaced by "tf-a-stm32mp157f-dk2-optee-programmer-uart.stm32".
The modified file "FlashLayout_sdcard_stm32mp157f-dk2-optee_uart.tsv" iss:
#opt Id Name Type Device Offset Binary - 0x01 fsbl-boot Binary none 0x0 arm-trusted-firmware/tf-a-stm32mp157f-dk2-optee-programmer-uart.stm32 - 0x03 fip-boot FIP none 0x0 fip/fip-stm32mp157f-dk2-optee-programmer-usb.bin
And the command to load U-Boot is:
STM32_Programmer_CLI -c port=/dev/ttyACM0 -w flashlayout_st-image-weston/optee/FlashLayout_sdcard_stm32mp157f-dk2-optee_uart.tsv
If you have adapted OP-TEE and U-Boot to use a different UART serial, you need to adapt also the fip-boot binary.
4.2. Program bootloaders[edit | edit source]
If you want program the bootloaders on boot device with UART with STLink, it is recommended to change the baudrate at 1MB/s.
4.2.1. Update TF-A BL2[edit | edit source]
Recompile TF-A BL2 with compilation flag STM32MP_UART_BAUDRATE=1000000 and replace the OpenSTLinux file
- arm-trusted-firmware/tf-a-stm32mp157f-dk2-optee-programmer-uart.stm32
4.2.2. Update U-Boot in UART FIP[edit | edit source]
- update the U-Boot defconfig with
CONFIG_BAUDRATE=1000000
make stm32mp15_defconfig make DEVICE_TREE=stm32mp157f-dk2 all
- update FIP file with the U-Boot binary:
cp fip/fip-stm32mp157f-dk2-optee-programmer-usb.bin fip/fip-stm32mp157f-dk2-optee-programmer-uart.bin fiptool --verbose update --nt-fw u-boot-nodtb.bin --hw-config u-boot.dtb fip/fip-stm32mp157f-dk2-optee-programmer-uart.bin
4.2.3. Create UART flashlayout file[edit | edit source]
Found after this new UART file "FlashLayout_sdcard_stm32mp157f-dk2-optee_uart.tsv" using:
- the UART TF-A BL2 binary tf-a-stm32mp157f-dk2-optee-programmer-uart.stm32
- the updated FIP fip-stm32mp157f-dk2-optee-programmer-uart.bin
- use empty file system partitions to only program the bootloaders
#opt Id Name Type Device Offset Binary - 0x01 fsbl-boot Binary none 0x0 arm-trusted-firmware/tf-a-stm32mp157f-dk2-optee-programmer-uart.stm32 - 0x03 fip-boot FIP none 0x0 fip/fip-stm32mp157f-dk2-optee-programmer-uart.bin P 0x04 fsbl1 Binary mmc0 0x00004400 arm-trusted-firmware/tf-a-stm32mp157f-dk2-optee-sdcard.stm32 P 0x05 fsbl2 Binary mmc0 0x00044400 arm-trusted-firmware/tf-a-stm32mp157f-dk2-optee-sdcard.stm32 PD 0x06 metadata1 FWU_MDATA mmc0 0x00084400 arm-trusted-firmware/metadata.bin PD 0x07 metadata2 FWU_MDATA mmc0 0x000C4400 arm-trusted-firmware/metadata.bin P 0x08 fip-a FIP mmc0 0x00104400 fip/fip-stm32mp157f-dk2-optee-sdcard.bin PED 0x09 fip-b FIP mmc0 0x00504400 none PED 0x0A u-boot-env ENV mmc0 0x00904400 none PE 0x10 bootfs System mmc0 0x00984400 none PE 0x11 vendorfs FileSystem mmc0 0x04984400 none PE 0x12 rootfs FileSystem mmc0 0x05984400 none PE 0x13 userfs FileSystem mmc0 0x105984400 none
4.2.4. Program the board[edit | edit source]
- Select serial boot on the board with BOOT pin and reset the board (the red LED is blinking until UART connection)
- On HOST execute the STM32CubeProgrammer command:
STM32_Programmer_CLI -c port=/dev/ttyACM0 br=1000000 -w flashlayout_st-image-weston/optee/FlashLayout_sdcard_stm32mp157f-dk2-optee_uart.tsv
- Select the correct boot mode and reboot the board.
The bootloaders are executed up to U-Boot console, ready to update the partitions needed by Linux kernel boot (see How_to_manually_update_bootloaders for examples).