From 1cfa5a47def4f21e6269eeafc516b3575b40338a Mon Sep 17 00:00:00 2001 From: David Lenfesty Date: Sun, 22 Jan 2023 15:20:27 -0700 Subject: [PATCH] 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. --- firmware/.cargo/config | 8 ++ firmware/.gitignore | 2 + firmware/Cargo.lock | 183 ++++++++++++++++++++++++++++++++ firmware/Cargo.toml | 10 ++ firmware/README.md | 3 + firmware/build.rs | 14 +++ firmware/hello_world_c/Makefile | 2 +- firmware/hello_world_c/main.c | 32 +++++- firmware/memory.x | 12 +++ firmware/src/main.rs | 33 ++++++ 10 files changed, 293 insertions(+), 6 deletions(-) create mode 100644 firmware/.cargo/config create mode 100644 firmware/.gitignore create mode 100644 firmware/Cargo.lock create mode 100644 firmware/Cargo.toml create mode 100644 firmware/README.md create mode 100644 firmware/build.rs create mode 100644 firmware/memory.x create mode 100644 firmware/src/main.rs diff --git a/firmware/.cargo/config b/firmware/.cargo/config new file mode 100644 index 0000000..5ca804d --- /dev/null +++ b/firmware/.cargo/config @@ -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" \ No newline at end of file diff --git a/firmware/.gitignore b/firmware/.gitignore new file mode 100644 index 0000000..cdc8c75 --- /dev/null +++ b/firmware/.gitignore @@ -0,0 +1,2 @@ +target/ +*.bin \ No newline at end of file diff --git a/firmware/Cargo.lock b/firmware/Cargo.lock new file mode 100644 index 0000000..cc42d99 --- /dev/null +++ b/firmware/Cargo.lock @@ -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" diff --git a/firmware/Cargo.toml b/firmware/Cargo.toml new file mode 100644 index 0000000..e2c8e57 --- /dev/null +++ b/firmware/Cargo.toml @@ -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" diff --git a/firmware/README.md b/firmware/README.md new file mode 100644 index 0000000..0104507 --- /dev/null +++ b/firmware/README.md @@ -0,0 +1,3 @@ +# Firmware + +This was set up according to docs here: https://docs.rs/riscv-rt/latest/riscv_rt/ \ No newline at end of file diff --git a/firmware/build.rs b/firmware/build.rs new file mode 100644 index 0000000..8709ff2 --- /dev/null +++ b/firmware/build.rs @@ -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"); +} \ No newline at end of file diff --git a/firmware/hello_world_c/Makefile b/firmware/hello_world_c/Makefile index d1edfbe..d471531 100644 --- a/firmware/hello_world_c/Makefile +++ b/firmware/hello_world_c/Makefile @@ -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 diff --git a/firmware/hello_world_c/main.c b/firmware/hello_world_c/main.c index c295dc4..ae2c91b 100644 --- a/firmware/hello_world_c/main.c +++ b/firmware/hello_world_c/main.c @@ -1,13 +1,28 @@ #include "uart.h" #include +#include 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); +} diff --git a/firmware/memory.x b/firmware/memory.x new file mode 100644 index 0000000..11e0748 --- /dev/null +++ b/firmware/memory.x @@ -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); diff --git a/firmware/src/main.rs b/firmware/src/main.rs new file mode 100644 index 0000000..27ad0e5 --- /dev/null +++ b/firmware/src/main.rs @@ -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); } +} \ No newline at end of file