Building,Flashing and Debugging Embedded Rust Program

Building Program

  • Cargo provides 4 different targets that cover the different processor families within that architecture.
    • thumbv6m-none-eabi, for the Cortex-M0 and Cortex-M1 processors

    • thumbv7m-none-eabi, for the Cortex-M3 processor

    • thumbv7em-none-eabi, for the Cortex-M4 and Cortex-M7 processors

    • thumbv7em-none-eabihf, for the Cortex-M4F and Cortex-M7F processors

  • The one we are interested in is the last one (i.e. thumbv7em-none-eabihf) because F3 has a Cortex-M4F processor in it.  
  • Before cross-compiling, we have to download a pre-compiled version of the standard library. For that we have to run:

$ rustup target add thumbv7em-none-eabihf

  • We have to download it once after that it will be updated automatically whenever we update the Rust toolchain. 
  • All set, we can now compile our program for whatever target we are compiling, using the following command:

$ cargo build –target thumbv7em-none-eabihf

Flashing Program

Flashing => Moving program to MCU’s memory

Every time MCU will power on it will run the program flashed last time.


  1. Launch OpenOCD 
  2. Open GDB Server console 
  3. Connect GDB Server to OpenOCD 
  4. Load the program

 Launcing OpenOCD

We saw already what is OpenOCD, now let’s see how it works and how to initiate it. First, we see how to initiate:

  1. Open up a new terminal

  2. Change directory to /temp (i.e. $ cd /tmp)

  3. Next, run this command

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


Now look at the above command carefully and the image below.


 Launching OpenOCD


We may observe that first, we are interacting with st-link to target stm32f303. The ST-LINK unveils a communication channel for us to target.

Initiating GDB Server

These commands are only specific to the gdb console. They haven’t any meaning to our normal terminal/command prompt.

1.    $ <gdb> -q target/thumbv7em-none-eabihf/debug/<project-name>

<gdb> => this is System dependent debugging program to read arm binaries. It has 3 ariants gdb, gdb-multiarch* and arm-none-eabi-gdb

*In our case gdb-multiarch will work.

target/thumbv7em-none-eabihf/debug/<project-name> => Path to the binaries of projects we want to flash in MCU. 

Connecting OpenOCD

The previous command only opens the gdb shell. To connect to Openocd      GDB Server run the following command.

2.    (gdb) target remote:3333

This 3333 highlights the port number on which the GDB server listens to requests. And this command connects us to this port.

Connecting OpenOCD Above is the result of this command.

Loading Program

Now the final step is to flash our code to MCU’s persistent memory, once we connected successfully,

3.    (gdb) load

Debugging Program

Our program stopped at the entry point after the load command. There are a few useful commands used for debugging purposes.

  • break

  • continue

break => this command is used to break the program at a certain point. For instance: We will run: (gdb) break main if we want to stop the program at the start of the main function. continue => this command would take us from one breakpoint to another breakpoint.

We may switch to GDB Text User Interface (TUI), for that run: (gdb) layout src, for viewing line by line execution of the program.  

We may run: (gdb) tui disable, for disabling TUI mode. While debugging run for resetting the program to initial state : (gdb) monitor reset halt. For terminating the GDB session     (gdb) quit

Further commands:

  • step: for moving to the next line

  • print: for printing values of variables

  • Info locals: this is for printing all values of variables at once

  • Clear shell: for clearing the TUI screen



Mansoor Ahmed

Mansoor Ahmed is Chemical Engineer, web developer, a Tech writer currently living in Pakistan. My interests range from technology to web development. I am also interested in programming, writing, and reading.