Hello world
The goal of this first step is to blink the LED and send strings to user over semi-hosting.
Follows blinky example from stm32f4xx-hal
Dependencies
cortex-m
: micro-architecture crate for cortex-m MCUs; routines and peripherals common to all micro-controllers using a particular processor corecortex-m-rt
: startup code and minimal runtime for cortex-m MCUsstm32f4xx-hal
: HAL for STM32F4 MCUs; use features = ["rt", "stm32f411"]cortex-m-semihosting
: implementation for communication over semihostingpanic-halt
: specifies panic behaviour (halt)
Memory file
cortex-m-rt
crate expects users to specify a memory.x file that specifies FLASH and
RAM memory regions.
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 512K
RAM : ORIGIN = 0x20000000, LENGTH = 128K
}
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
.cargo/config file
It specifices the build target for cross-compilation
[target.thumbv7em-none-eabihf]
rustflags = [
"-C", "link-arg=-Tlink.x",
]
[build]
target = "thumbv7em-none-eabihf"
Code
#![no_main]
#![no_std]
use panic_halt as _;
use cortex_m;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
use stm32f4xx_hal as hal;
use crate::hal::{prelude::*, stm32};
#[entry]
fn main() -> ! {
if let (Some(dp), Some(cp)) = (
stm32::Peripherals::take(),
cortex_m::peripheral::Peripherals::take()
) {
// set up the LED (PC13)
let gpioc = dp.GPIOC.split();
let mut led = gpioc.pc13.into_push_pull_output();
// set up the system clock
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.sysclk(100.mhz()).freeze();
// create a delay abstraction based on system tick
let mut delay = hal::delay::Delay::new(cp.SYST, clocks);
loop {
led.set_high().unwrap();
delay.delay_ms(1000_u32);
led.set_low().unwrap();
delay.delay_ms(1000_u32);
hprintln!("Hello world!").unwrap();
}
}
loop {}
}
Appendix
The following sections contain reference material unrelated to the core project that you may find useful.
Appendix A: Setting up documentation
This documentation was built with mdBook. It is a rust crate to create books using Markdown. The book is automatically deployed to Github pages using this action.
Appendix B: Flashing firmware to hardware
Flashing with OpenOCD and GDB
Start OpenOCD
openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg
Start GDB with the elf file
gdb-multiarch target/thumbv7em-none-eabihf/debug/line-following-bot
Then run the following commands in GDB
target remote :3333
load
quit
Note: Semihosting can be enabled with the following gdb command:
monitor arm semihosting enable
Flashing with DFU-util
DFU-util requires a binary file. The rust ELF file can be converted using objcopy
arm-none-eabi-objcopy -O binary target/thumbv7em-none-eabihf/release/line-following-bot target/thumbv7em-none-eabihf/release/line-following-bot.bin
Flash with DFU-util
dfu-util -a0 --dfuse-address 0x08000000 -D target/thumbv7em-none-eabihf/release/line-following-bot.bin
Appendix C: Hardware
Hardware: