-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feature request] add Rust support #837
Comments
Hey @Chris44442! That's an interesting idea! I've never worked with Rust before, but I see it being adopted more and more - even in tiny embedded systems (which have a focus on security). So, yes, I would love to see this project support Rust. Unfortunately, I'm far too inexperienced to tackle it.
That sounds great! Could you make the sources available some where? Maybe that would be a good starting point. |
Several CPU extensions are disabled by default: https://github.com/stnolting/neorv32/blob/main/rtl/core/neorv32_top.vhd#L59-L71. You might try enabling them all. Alternatively, when compiling your Rust program, you might try checking how to specify |
This is my main.rs #![no_std]
#![no_main]
use core::panic::PanicInfo;
const GPIO_BASE: usize = 0xffff_fc08;
#[no_mangle]
pub extern "C" fn _start() -> ! {
let gpio_output_val = GPIO_BASE as *mut u32;
let mut result: u32 = 0;
unsafe {gpio_output_val.write_volatile(result);}
result = result + 5;
unsafe {gpio_output_val.write_volatile(result);}
result = 3 * result;
unsafe {gpio_output_val.write_volatile(result);}
result = result - 2;
unsafe {gpio_output_val.write_volatile(result);}
if result == 1 {
unsafe {gpio_output_val.write_volatile(0x0000_0001);}
}
else if result == 13 {
unsafe {gpio_output_val.write_volatile(0x0000_3333);}
}
else {
unsafe {gpio_output_val.write_volatile(0x0000_0010);}
}
loop {}
}
#[panic_handler]
fn panic (_info: &PanicInfo) -> ! {
loop {}
} and my Cargo.toml [package]
name = "neorv32_rusty"
version = "0.1.0"
edition = "2021"
[dependencies]
[[bin]]
name = "neorv32_rusty"
test = false
bench = false and my config.toml [build]
target = "riscv32imc-unknown-none-elf" *I have also tried riscv32i-unknown-none-elf as the target, but I haven't noticed a difference. So my guess is that the problem is not the rust compiler generating unsupported instructions, but something else. my vhdl instantiation neorv32_top_inst: entity work.neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => 50000000, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => false, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension?
CPU_EXTENSION_RISCV_M => true, -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
-- Internal Instruction memory --
MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => 17*1024, -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN => true, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => 8*1024, -- size of processor-internal data memory in bytes
-- Processor peripherals --
IO_GPIO_NUM => 8, -- number of GPIO input/output pairs (0..64)
IO_MTIME_EN => true -- implement machine system timer (MTIME)?
)
port map (
-- Global control --
clk_i => FPGA_CLK1_50, -- global clock, rising edge
rstn_i => hps_fpga_reset_n, -- global reset, low-active, async
-- GPIO (available if IO_GPIO_NUM > 0) --
gpio_o(0) => LED(0), -- parallel output
gpio_o(1) => LED(1), -- parallel output
gpio_o(2) => LED(2), -- parallel output
gpio_o(3) => LED(3), -- parallel output
gpio_o(4) => LED(4), -- parallel output
gpio_o(5) => LED(5), -- parallel output
gpio_o(6) => LED(6) -- parallel output
);
To get it working I simply replace one of the main.elf files from the software examples with my compiled rust elf binary, comment out I have made a few more tests and right now my suspicion is that any loops results in jumps to the wrong address. One thing to note is that Rust elf files seem to look a bit different, if you inspect them with a hex editor compared to C elf files. If statements seem to work, and I have also tested some u32 and f64 calulations which did seem to work. But, even the infinite loop at the end of the program can result in unexpected behavior. Maybe I will try to dig deeper in the next few days. But I have just started learning risc-v so my experience is limited. |
Unfortunately, I still haven't found the time to try it out myself. Anyway, thanks for sharing your code! Rust is definitely on my want-to-learn list 😉 |
One suggestion is to look at the ibex code: https://github.com/lowRISC/ibex-demo-system/blob/main/sw/rust/demo/led_hal/src/main.rs they have several rust examples running on their version of the risc-v with builds for the Arty board .... #![no_main]
#![no_std]
extern crate panic_halt as _;
use core::fmt::Write;
use embedded_hal::blocking::delay::DelayMs;
use riscv::delay::McycleDelay;
use riscv_rt::entry;
use embedded_hal;
use embedded_hal::digital::v2::{InputPin, OutputPin};
use hal::{pac, ErasePin, GpioExt};
use ibex_demo_system_hal as hal; In the Cargo toml file they reference it in their dependencies : [dependencies]
panic-halt = "0.2.0"
riscv = {version = "0.10.1", features = ["critical-section-single-hart"]}
riscv-rt = "0.11.0"
ibex-demo-system-hal = {path = "../../ibex-demo-system-hal"}
embedded-hal = "0.2.7" |
Recently I have tried converting a Rust elf binary to the neorv32_application_image.vhd, by making a minor hack to the common.mk file. To my surprise it worked pretty much right away. My Rust program was very simple, essentially I only wrote to a couple of physical addresses (GPIOs) in order to toggle the LEDs on my board. But even calculating some trigonometric floating point stuff worked! But as soon as I added things like loops and more complex stuff, it didn't work anymore. My guess is that the instructions in the neorv32_application_image.vhd were not valid for some reason. I haven't tried using the bootloader yet due to my hardware setup.
Anyway this got my hopes up, that we may have Rust support in the future in some way?
The text was updated successfully, but these errors were encountered: