firmware: made some rust firmware to test

Had some issues due to lack of startup code (stack pointer was unset,
leading to underflow in address space), so decided to just get the rust
FW started instead of finding some startup code to use.
This commit is contained in:
David Lenfesty 2023-01-22 15:20:27 -07:00
parent a1853dbe81
commit 1cfa5a47de
10 changed files with 293 additions and 6 deletions

8
firmware/.cargo/config Normal file
View File

@ -0,0 +1,8 @@
[target.riscv32i-unknown-none-elf]
rustflags = [
"-C", "link-arg=-Tmemory.x",
"-C", "link-arg=-Tlink.x",
]
[build]
target = "riscv32i-unknown-none-elf"

2
firmware/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target/
*.bin

183
firmware/Cargo.lock generated Normal file
View File

@ -0,0 +1,183 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "bit_field"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]]
name = "critical-section"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52"
[[package]]
name = "embedded-hal"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
"nb 0.1.3",
"void",
]
[[package]]
name = "fw"
version = "0.1.0"
dependencies = [
"panic-halt",
"riscv-rt",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "nb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
"nb 1.0.0",
]
[[package]]
name = "nb"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
[[package]]
name = "panic-halt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
[[package]]
name = "proc-macro2"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r0"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211"
[[package]]
name = "regex"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "riscv"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa3145d2fae3778b1e31ec2e827b228bdc6abd9b74bb5705ba46dcb82069bc4f"
dependencies = [
"bit_field",
"critical-section",
"embedded-hal",
]
[[package]]
name = "riscv-rt"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "102c52c89defde24dedf9ac077cc69df77b85aa2400dd2d5aad6eea6a6a5c089"
dependencies = [
"r0",
"riscv",
"riscv-rt-macros",
"riscv-target",
]
[[package]]
name = "riscv-rt-macros"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38509d7b17c2f604ceab3e5ff8ac97bb8cd2f544688c512be75c715edaf4daf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "riscv-target"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222"
dependencies = [
"lazy_static",
"regex",
]
[[package]]
name = "syn"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

10
firmware/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "fw"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
riscv-rt = "0.11.0"
panic-halt = "0.2.0"

3
firmware/README.md Normal file
View File

@ -0,0 +1,3 @@
# Firmware
This was set up according to docs here: https://docs.rs/riscv-rt/latest/riscv_rt/

14
firmware/build.rs Normal file
View File

@ -0,0 +1,14 @@
use std::env;
use std::fs;
use std::path::PathBuf;
fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
// Put the linker script somewhere the linker can find it.
fs::write(out_dir.join("memory.x"), include_bytes!("memory.x")).unwrap();
println!("cargo:rustc-link-search={}", out_dir.display());
println!("cargo:rerun-if-changed=memory.x");
println!("cargo:rerun-if-changed=build.rs");
}

View File

@ -2,7 +2,7 @@ PREFIX := riscv64-unknown-elf-
CC := $(PREFIX)gcc
OBJCOPY := $(PREFIX)objcopy
ARGS := -mabi=ilp32 -march=rv32im -ffreestanding -nostdlib -Wl,-Bstatic,-T,memory.ld,--strip-debug
ARGS := -mabi=ilp32 -march=rv32im -ffreestanding -nostdlib -Wl,-Bstatic,-T,memory.ld -g
SOURCES := main.c
INCLUDES := uart.h

View File

@ -1,13 +1,28 @@
#include "uart.h"
#include <stdint.h>
#include <stdbool.h>
void write_cstring(const char* string);
void write_char(char c);
void toggle_led();
#define LED *((uint32_t*) 0x01002000)
int main() {
uint32_t i = 0;
bool toggle = false;
for (;;) {
if (i >= 100) {
i = 0;
if (toggle) {
LED = 1;
} else {
LED = 0;
}
}
write_char('H');
write_char('e');
write_char('l');
@ -22,17 +37,19 @@ int main() {
write_char('!');
write_char('\n');
write_char('\r');
i += 1;
}
}
void write_char(char c) {
while (!UART0->TXEMPTY);
//while (!UART0->TXEMPTY);
// Wait for room to clear up
if (!UART0->TXFULL) {
UART0->RXTX = c;
}
//// Wait for room to clear up
//if (!UART0->TXFULL) {
// UART0->RXTX = c;
//}
}
void write_cstring(const char* string) {
int i = 0;
@ -52,3 +69,8 @@ void write_cstring(const char* string) {
}
}
void toggle_led() {
LED = !LED;
write_char('0' + LED);
}

12
firmware/memory.x Normal file
View File

@ -0,0 +1,12 @@
MEMORY
{
RAM : ORIGIN = 0x01001000, LENGTH = 4K
FLASH : ORIGIN = 0x01000000, LENGTH = 4K
}
REGION_ALIAS("REGION_TEXT", FLASH);
REGION_ALIAS("REGION_RODATA", FLASH);
REGION_ALIAS("REGION_DATA", RAM);
REGION_ALIAS("REGION_BSS", RAM);
REGION_ALIAS("REGION_HEAP", RAM);
REGION_ALIAS("REGION_STACK", RAM);

33
firmware/src/main.rs Normal file
View File

@ -0,0 +1,33 @@
#![no_std]
#![no_main]
extern crate panic_halt;
use core::{arch::asm, ptr::write};
use riscv_rt::entry;
// use `main` as the entry point of this application
// `main` is not allowed to return
#[entry]
fn main() -> ! {
// do something here
loop {
unsafe {
write(0x01002000 as *mut u32, 0);
busy_wait(10_000_000);
write(0x01002000 as *mut u32, 1);
busy_wait(10_000_000);
}
}
}
fn busy_wait(num_nops: u32) {
for _ in 0..num_nops {
unsafe { asm!("nop"); }
}
}
fn write_led(val: u32) {
unsafe { write(0x01002000 as *mut u32, val); }
}