[−][src]Crate fomu_rt
Minimal startup / runtime for RISC-V Fomu CPU
Minimum Supported Rust Version (MSRV)
This crate is guaranteed to compile on stable Rust 1.31 and up. It might compile with older versions but that may change in any new patch release.
Features
This crate provides
-
Before main initialization of the
.bss
and.data
sections. -
#[entry]
to declare the entry point of the program -
#[pre_init]
to run code beforestatic
variables are initialized -
A linker script that encodes the memory layout of a generic RISC-V microcontroller. This linker script is missing some information that must be supplied through a
memory.x
file (see example below). This file must be supplied using rustflags and listed beforelink.x
. Arbitrary filename can be use instead ofmemory.x
. -
A
_sheap
symbol at whose address you can locate a heap.
$ cargo new --bin app && cd $_
$ # add this crate as a dependency
$ edit Cargo.toml && cat $_
[dependencies]
fomu-rt = "0.0.1"
panic-halt = "0.2.0"
$ edit src/main.rs && cat $_
#![no_std] #![no_main] extern crate panic_halt; use fomu_rt::entry; // use `main` as the entry point of this application // `main` is not allowed to return #[entry] fn main() -> ! { // do something here loop { } }
$ mkdir .cargo && edit .cargo/config && cat $_
[target.riscv32i-unknown-none-elf]
rustflags = [
"-C", "link-arg=-Tlink.x",
]
[build]
target = "riscv32i-unknown-none-elf"
$
$ cargo build
$ riscv32-unknown-elf-objdump -Cd $(find target -name app) | head
Disassembly of section .text:
20000000 <_start>:
20000000: 800011b7 lui gp,0x80001
20000004: 80018193 addi gp,gp,-2048 # 80000800 <_stack_start+0xffffc800>
20000008: 80004137 lui sp,0x80004
Symbol interfaces
This crate makes heavy use of symbols, linker sections and linker scripts to provide most of its functionality. Below are described the main symbol interfaces.
Example
extern crate some_allocator; extern "C" { static _sheap: u8; static _heap_size: u8; } fn main() { unsafe { let heap_bottom = &_sheap as *const u8 as usize; let heap_size = &_heap_size as *const u8 as usize; some_allocator::initialize(heap_bottom, heap_size); } }
_mp_hook
This function is called from all the harts and must return true only for one hart, which will perform memory initialization. For other harts it must return false and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
This function can be redefined in the following way:
#[export_name = "_mp_hook"] pub extern "Rust" fn mp_hook() -> bool { // ... }
Default implementation of this function wakes hart 0 and busy-loops all the other harts.
Functions
start_rust⚠ | Rust entry point (_start_rust) |
start_trap_rust | Trap entry point rust (_start_trap_rust) |
Attribute Macros
entry | Attribute to declare the entry point of the program |
pre_init | Attribute to mark which function will be called at the beginning of the reset handler. |