Embedded-Rust: Build & Flash binary to STM32F3DISCOVERY

Knoldus Blog Audio
Reading Time: 5 minutes

An embedded system is computer hardware with software embedded in it. Or we can say it is a combination of computer processors, computer memory, and input/output devices and it can be an independent system or a part of a large system.

Hi folks, we are back again with another interesting article which is actually a continuation of our previous part. In this article, we’ll gonna take a look at why our binary doesn’t have a valid Entry point address and we’ll also try to flash the binary into our board (STM32F3DISCOVERY).
Alright!!! let’s start to update our knowledge pool by adding one more interesting row in it.

In our previous article, we were able to cross-compile our binary successfully however after validating it we got to know, the cross-compiled binary doesn’t contain a valid entry point address. Now, the question arises why???

The reason behind this is we haven’t provided a memory layout of the target device via linker script that’s why the cross-compiled binary doesn’t have a valid entry point address.

Let’s provide a memory layout

To provide a memory layout we need to add a linker script named memory.x which specifies the memory available in the device. The content of memory.x contains at least two MEMORY regions FLASH and RAM. To be more precise the .text and .rodata sections of the program will be placed in the FLASH region, whereas the .bss and .data sections, as well as the heap, will be placed in the RAM region.
Now we got enough information about the linker script, now let’s provide it for our board which is SMT32F3Discvoery.

/* memory.x(file_name) */
/* Linker script for the STM32F303VCT6 */
MEMORY
{
  /* 1 K = 1 KiBi = 1024 bytes */
  FLASH : ORIGIN = 0x08000000, LENGTH = 256K
  RAM : ORIGIN = 0x20000000, LENGTH = 40K
}

We have to place this linker script somewhere so that the linker can find it. So we’ll place this parallel to our source directory. Like this:

Now, our next step is to provide the configuration so that our program uses the correct linker script.

Configuration

We’ll be providing configuration via .cargo/config.toml file.

# .cargo/config.toml

[target.thumbv7em-none-eabihf]

# use Tlink.c script from the cortex-m-rt crate
rustflags = [
    "-C", "link-arg=-Tlink.x",
]

In the above file, we linked our program using cortex-m-rt‘s linker script: link.x with the help of rustflags for a target thumbv7em-none-eabihf.

Alright!! we have provided the target’s memory layout via linker script and linked it with the program as well, now we all set to re-compile the binary for our STM32Discovery board.

Let’s recompile it using:

cargo build --target thumbv7em-none-eabihf

Okay, the binary is successfully cross-compiled, now let’s check its header using cargo’s readobj:

cargo readobj --target thumbv7em-none-eabihf --bin stm32 -- --file-header

Great!!! this time we got a valid value for entry point address, it means this binary has a valid starting point.

So without any further delay, let’s flash this binary into the microcontroller(STM32F3Discvoery).

Flash the binary

The term flashing means moving our program into the microcontroller’s memory. It means our binary will be the only program in the microcontroller’s memory, in other words, our binary will have full control over the broad.

To actually flash the binary, firstly we need to launch OpenOCD(Open On-Chip Debugger), which is used to provide debugging, in-system programming, and boundary-scan testing for embedded target devices and provides some services like a GDB server. Secondly, we need to execute the GDB. Thirdly, and most importantly, loading the binary into the board.

Before proceeding further, let’s try to understand what will happen under the hood when we follow the above-mentioned steps.
SMT32F3Discovery(F3) board has two micro-controllers, ST-LINK, and STM32F303. ST-LINK is used as a programmer/debugger and it is connected to STM32F303(target micro-controller) using SWD(Serial Wire Debug) interface which is used to debug and flash a micro-controller. And also connected with the USB ST-LINK port so that it can act as a USB device.

Now, let’s take a look at the OpenOCD command:

openocd -f interface/stlink-v2-1.cfg -f target/stm32f3x.cfg

Here, we are instructing OpenOCD to look for an ST-LINK USB device by specifying interface/stlink-v2-1.cfg and expecting an STM32F3XX microcontroller to be connected to the `ST-LINK` by this target/stm32f3x.cfg.
Let’s fire the OpenOCD in temp directory after connecting F3 with the computer:

Launch OpenOCD

It indicates we have 6 breakpoints and 4 watchpoints available.
Now our next step is to execute the GDB server:

Execute GDB service

gdb-multiarch -q -ex "target remote :3333" target/thumbv7em-none-eabihf/debug/smt32

gdb-multiarch -q is the version of the GDB server, we can select any version that works for us. After the version, we specified the target location (target remote :3333) as the GDB server listens on TCP port 3333, and at last, we just provided the path to the cross-compiled binary.

Let’s fire this command:

These instruction shows that we have successfully executed our GDB server. And if we look at the OpenOCD console we got something like this:

Alright!! now it’s time to actually load our binary into the Microcontroller.

Load the binary

To load binary we just need to trigger a load command in GDB console, like this:

This shows our binary is loaded and logs are reflected in the OpenOCD console as well:

This confirms that the binary is successfully loaded into the microcontroller(STM32F3Discovery).

That’s all about this article, in the next article we’ll try to play with some components of the STM32F3Discovery board.
Thanks for reading!!!

References:

If you want to read more content like this?  Subscribe Rust Times Newsletter and receive insights and latest updates, bi-weekly, straight into your inbox. Subscribe Rust Times Newsletter: https://bit.ly/2Vdlld7 .


Knoldus-blog-footer-image

Written by 

Pawan Singh Bisht is a Software Consultant at Knoldus Software LLP, having a strong experience of more than two years in the technology field. He has been well versed in the core implementation of Rust and Java. He loves to contribute to the community which he attained from the community.

2 thoughts on “Embedded-Rust: Build & Flash binary to STM32F3DISCOVERY7 min read

Comments are closed.