Setup of Rust Development Environment
Add Target for Arm architecture
Add the compiling for arm architecture if not on an armv7 processor
rustup target add armv7a-none-eabi
Create Rust Package
Create a Cargo package and include the dependencies
Use: cargo new ‘package name’ package
This will create a package name directory with Cargo.toml and src directory with main.rs
Setup rust to compile for Arm without linux
In package name directory create a directory called .cargo
and add a file called config
In the config file add the build configuration for the Processor used in the Raspberry Pi
Pi3 B+ uses ARMv7
Setting up Code File
Adjust the main.rs to not include any standard libraries
adjust the code entry point, to not use main( ) as a start( ) function will be used
make the start function globally accessible for linking so it is ordered the right way
provide external label C and make it manageable by using #![no mangle]
Create Panic
Provide a state panic handler to catch and resolve errors encountered in code
use core::panic::PanicInfo;
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[no_mangle]
pub extern "C" fn _start() -> ! {
loop{}
}
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop{}
}
With this minimum code setup running the command cargo build should complete successfully to indicate Rust is configured.
Use ELF Binary File Reader
If using Windows download and install XELFviewer from github
https://github.com/horsicq/XELFViewer/releases
Extract contents of zip file and run xelfviewer.exe
Open the Object Dump File created by Rust (name will match the rust package name)
To install in debian based distro Install the following
sudo apt-get install file
sudo apt-get elfrc elfutils libasm1
sudo apt-get install gcc-arm-none-eabi
Create Linker Script
Next the Hex Code for the start address needs to be set by the Linker Script when building the solution.
In the package folder create text file called linker.ld and set the following script
ENTRY(_start)
SECTIONS
{
. = 0x8000;
__start = .;
.text :
{
KEEP(*(.text.boot))
*(.text)
}
. = ALIGN(4096);
.rodata :
{
*(.rodata)
}
. = ALIGN(4096);
.data :
{
*(.data)
}
. = ALIGN(4096);
__bss_start = .;
.bss :
{
bss = .;
*(.bss)
}
. = ALIGN(4096);
__bss_end = .;
__bss_size = __bss_end - __bss_start;
__end = .;
}
Add to main.rs
#![no_std]
#![no_main]
use core::panic::PanicInfo;
mod boot {
use core::arch::global_asm;
global_asm!(
".section .text._start"
);
}
#[no_mangle]
pub extern "C" fn _start() -> ! {
loop{}
}
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop{}
}
Run the rust compiler this time with the linker script. *Delete Target Folder whenever you modify the linker.ld file.
cargo rustc -- -C link-arg=--script=.\linker.ld
Next the unusable code generated for Linux must be removed to run on bare metal RaspberryPi
The code to run on the RaspberryPi must be extracted from the ELF file.
arm-none-eabi-objcopy -O binary rust_pi_embedded ./rust_pi.img
This will create the executable code that will run on the raspberry pi as “baremetal” without Linux OS
Reference Documentation for GPIO
When designing software for the hardware of RaspberryPi without Linux the Broadcom BCM3837 ARM Peripherals manual should be used. Official RasberryPi Links
Set Pin to GPIO
Setting up GPIO pins
Setting Pin 21 to on and off.
Select Pin From the datasheet and copy the register address
Add a do nothing loop
Setting Up i2c
Firmware Files
Download Github Firmware files
From the github repository download and install files required to run the image on the RaspberryPi
https://github.com/raspberrypi/firmware/blob/master/boot/bootcode.bin
https://github.com/raspberrypi/firmware/blob/master/boot/fixup.dat
https://github.com/raspberrypi/firmware/blob/master/boot/start.elf
Create Config
Create a file config.txt include the following configuration settings
arm_64bit=0
Combine the Files into a directory
copy the files into a directory: bootcode.bin fixup.dat start.elf config.txt kernel7.img
to boot partition