Rust Only RaspberryPi Embedded

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)

Make note of the Entry point address: 000200e4
This needs to be changed to 0008000e4 in linker

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
_start is now 0008000

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