-
Notifications
You must be signed in to change notification settings - Fork 569
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
examples: New app to build Rust with Cargo #2487
Conversation
[Experimental Bot, please feedback here] PR Requirements ReviewMeeting Requirements? Partially Summary:
Impact:
Testing:
Specific Concerns
RecommendationThis PR addresses a desirable feature but is not yet ready for merging in its current state. Address the concerns outlined above to ensure a robust, well-documented, and well-tested addition to NuttX. |
ping @no1wudi |
I'll continue this work next week |
055e551
to
4fe9be4
Compare
@no1wudi Thanks for the great job! What command shall I run to build this for QEMU RISC-V 64-bit? Might be good to include some minimal docs for this release thanks :-) |
@lupyuen I'll perpare a doc for it soon 😄 |
Hi @no1wudi, I'm really looking forward to this PR—great job! I’d be happy to help if you need an extra hand, especially with documentation. I do have a few questions, and apologies if they’re obvious:
Thanks again for your hard work. I’m excited to try it out! |
@lvanasse Thank you for offering your help. Regarding your questions, here's the current situation:
For most standard system (POSIX) interfaces, the functionality provided by the Rust standard library is sufficient, and the porting work for this part has already been completed on the Rust side. If you need to use NuttX-specific system interfaces, such as SPI/I2C/LCD drivers, you will need to create additional crates for those, as they fall outside the scope of the Rust standard library.
TODO #2 and #3 are now completed. As you can see, the current demo program can utilize the standard library, and even third-party native Rust libraries like serde_json and tokio, which heavily rely on the standard library, are now supported. I will provide a document as soon as possible to describe how to use the Rust standard library on NuttX. If possible, please help test it out and assist me in refining the related documentation. |
@lvanasse @lupyuen Please refer to this document to test it: apache/nuttx#15476 😄 |
@no1wudi Sorry did I miss something? This is for Ubuntu 24.04.1 LTS x86_64: $ rustup toolchain install nightly
$ rustup default nightly
$ git clone https://github.com/no1wudi/nuttx-apps apps --branch rust
$ git clone https://github.com/no1wudi/nuttx --branch build
$ cd nuttx
$ cmake -B build -DBOARD_CONFIG=rv-virt:nsh -GNinja .
$ cmake --build build -t menuconfig
## Enable CONFIG_SYSTEM_TIME64 / CONFIG_FS_LARGEFILE / CONFIG_TLS_NELEM = 16 / CONFIG_DEV_URANDOM / CONFIG_EXAMPLES_HELLO_RUST_CARGO = Y
## Disable CONFIG_ARCH_FPU
$ cmake --build build
error: "/home/luppy/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/Cargo.lock" does not exist, unable to build with the standard library, try:
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
$ rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
$ cmake --build build
[4/6] Building Rust crate hello
FAILED: apps/examples/hello_rust_cargo/hello/riscv32imac-unknown-nuttx-elf/release/libhello.a /home/luppy/rust/nuttx/build/apps/examples/hello_rust_cargo/hello/riscv32imac-unknown-nuttx-elf/release/libhello.a
cd /home/luppy/rust/nuttx/build/apps/examples/hello_rust_cargo && cargo build --release -Zbuild-std=std,panic_abort --manifest-path /home/luppy/rust/apps/examples/hello_rust_cargo/hello/Cargo.toml --target riscv32imac-unknown-nuttx-elf --target-dir /home/luppy/rust/nuttx/build/apps/examples/hello_rust_cargo/hello
Compiling gimli v0.31.1
Compiling object v0.36.7
Compiling addr2line v0.24.2
Compiling std v0.0.0 (/home/luppy/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std)
error[E0308]: mismatched types
--> /home/luppy/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/pal/unix/fs.rs:1047:33
|
1047 | unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) }
| -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `*const u8`, found `*const i8`
| |
| arguments to this function are incorrect
|
= note: expected raw pointer `*const u8`
found raw pointer `*const i8`
note: associated function defined here
--> /home/luppy/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ffi/c_str.rs:276:25
|
276 | pub const unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
| ^^^^^^^^
For more information about this error, try `rustc --explain E0308`.
error: could not compile `std` (lib) due to 1 previous error
ninja: build stopped: subcommand failed.
$ rustc --version
rustc 1.86.0-nightly (a580b5c37 2025-01-08) Here's my .config thanks :-) https://gist.github.com/lupyuen/7c646132ce0c81533203d6d6ccdbfb72 |
@lupyuen I had submitted a fix for this issue: rust-lang/libc#4222 For now, please modify the file, add a force cast locally: /home/luppy/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/pal/unix/fs.rs:1047:33:
|
Sorry @no1wudi why is
|
@xuxin930 We must set a fake source (https://github.com/apache/nuttx-apps/pull/2487/files#diff-9032963d33348a63e0ddf876c0f994b71375b5c62c5938f05a69466a8bdb464b) for nuttx_add_application then it can create a app in nsh correctly: Do you have any suggestions? |
9bd14ce
to
71a60b9
Compare
@no1wudi let's try this #2934 |
@no1wudi would you suggest use your https://github.com/no1wudi/nuttx.rs repo? Or should it be the NuttX project to have a nuttx-rs repository? I'm also seeing @lupyuen crate: https://crates.io/crates/nuttx-embedded-hal, could we utilise that? |
@lvanasse nuttx-embedded-hal is a very old crate, we might need to revamp it :-) |
This repository is quite old and was merely an attempt to implement APIs similar to those in Rust's standard library. Now that we have the actual Rust std library, there is no longer a need for it. Maybe we should create a new crate or continue |
Actually I'm not too clear if we should stick to the Official Rust Embedded HAL for NuttX. Here's why... To blink an LED in Rust Embedded HAL: We fetch the GPIO, then switch it off and on: https://docs.rust-embedded.org/discovery/microbit/05-led-roulette/light-it-up.html But there's no need to do this in NuttX! We simply open the LED Device Embedded HAL feels strange when we force-fit it into NuttX. I think I2C will have similar issues: https://lupyuen.github.io/articles/rusti2c#nuttx-embedded-hal If we look at Rust on Zephyr: They are proposing to use a Native Zephyr API to blink the LED #![no_std]
#![no_main]
#[zephyr::entry]
fn main() {
let dt = zephyr::devicetree::take().unwrap();
let led = dt.chosen.led0;
loop {
led.toggle().unwrap();
zephyr::sys::sleep(1000);
}
} My gut feel is that we should do it the Zephyr way. But make it POSIX-like. Thus we should drop Update: These look interesting... |
Thank you @lupyuen for the great research as always! What is your opinion on the idea of restarting the development of the NuttX API in the rustix crate? Would that make sense? And if not, we can always create our own nuttx-rs crate, maybe based on @no1wudi repo :)? Edit: And I agree the rust embedded hal is a bit awkward when it comes to supporting POSIX systems. I feel it is more meant to be used in bare-metal application. |
Thanks for your information, personally, I also lean towards providing NuttX APIs for Rust programs in a manner similar to Zephyr. This approach allows for full utilization of existing implementations and is based on POSIX-like APIs (entirely file operation-based). |
@lvanasse rustix is kinda heavy I think? It does Managed File Descriptors that will auto-close when they go out of scope. There might be a lot of dependencies inside? I wrote about it here: https://lupyuen.github.io/articles/rust6#handle-errors-safely
|
Sounds good, I'll follow your lead then :) I'll happyly help out where I can for this. |
Sorry I have other questions @no1wudi, what if we want to use And what about the development experience? When you write your code for the Rust application do you have access to the linter and etc? It's OK if that's not possible in either case. I can of want to understand if there's limitation and what we can improve :)? |
If your application solely utilizes APIs from the Rust standard library, executing
I guess the development experience is akin to that of regular Rust programs on a PC, as we are developing against the standard library. It's possible that we may introduce an additional crate in the future to provide interfaces for NuttX. Even if issues related to target settings arise, they can be resolved by adjusting the parameters of the linter, especially since support for NuttX has now been integrated into rustc itself. |
Sounds like a fun challenge :-) |
I think it's possible to support |
Build Rust applictions with cargo is the most commn way, and it's more easy to cooporate with Rust ecosystem. This example shows how to use cargo to build a simple hello world application. And please notice that you need to install nighly version of rustc to support this feature, any version after rust-lang/rust#127755 is merged, can use NuttX as cargo target directly. Build ----- To build hello_rust_cargo application, you can use any target that based on RISCV32IMAC, for example: ``` cmake -B build -DBOARD_CONFIG=rv-virt:nsh -GNinja . ``` And disable ARCH_FPU in menuconfig, since the hard coded target triple in this demo is `riscv32imac`. Signed-off-by: Huang Qi <[email protected]>
Build Rust applictions with cargo is the most commn way, and it's more easy to cooporate with Rust ecosystem.
This example shows how to use cargo to build a simple hello world application.
And please notice that you need to install nighly version of rustc to support this feature, any version after rust-lang/rust#127755 is merged, can use NuttX as cargo target directly.
Build
To build hello_rust_cargo application, you can use any target that based on RISCV or ARM, for example:
And disable ARCH_FPU in menuconfig, since the hard coded target triple in this demo is
riscv32imac
.TODO
Add support for Rust in CMake based systemUpstream https://github.com/no1wudi/libc to rust-lang/libcPort libstd of Rust to NuttX, which blocked by 2.UPDATE
Now you can just enable the example on many ARM/RISCV platform, build system will handle target triple for Rust.