Using Rust with RIOT-OS

I found the triangle to toggle now. Yeah, it’s a custom build command, and it seems that something is missing?

Thanks, I now had a different issue with iot-rust-module-studio/examples/esp32-no_std. Shared more details on Github.

Rust on RIOT needs nightly rust; you can set that using rustup override set nightly in your RIOT folder. Should probably add that to the docs, sorry.

Ad running without nightly: As long as relevant RIOT APIs are spec’d as static inline functions, we need nightly because that’s what C2Rust outputs (esp. given some of the inline functions use assembly). IMO the work to get this usable w/o nightly should start there as it’s the hardest. (Can start by removing any other nightly features too, if it matters to not depend on nightly).

The nightly situation may surprisingly become better – although not in the way I hoped.

The llvm_asm produced by C2Rust is about to be removed, which would break the workflows badly with some nightly coming out maybe mid-2022 (guess; no promises either direction).

On the flipside, I’ve investigated alternatives, and little of the produced assembly is actually called. (The expected exceptions being a few lines in toggling interrupts), and I have a sketch (see link) of how these few would be manually transcribed to Rust’s new assembly syntax.

The upshot of that is the new asm macros being stable; that being out of the way, we could start an effort to get the remaining nightly features out.

Rough summary:

  • from riot-sys:

    • #![feature(extern_types)] – when experimenting with C2Rust generated extern functions, C library fn are pulled in and they have stuff like pub type iovec. Would need revisiting, maybe that was just from when I tried going all the way with C2Rust (abandoning bindgen).
    • #![feature(core_intrinsics)] – Produced by c2rust for riscv32imac, eg. on hifive1 board (at least with TOOLCHAIN=llvm). Might be possible to work around using asm.
    • #![feature(const_raw_ptr_deref)] – Produced in const functions on the rpi-pico and ek-lm4f120xl boards, eg. when casting around LED_PORT. Will need investigation, maybe slight rephrasing of the C preprocessor phrasing would do here.
  • from riot-wrappers:

    • #![feature(never_type)] – can do without, back when I started that I thought that’d be stable soon. (The name should have given it away…) It’s just a breaking change in riot-wrappers.
    • #![feature(const_mut_refs)] – not sure what that was for (all the others were commented or obvious)
    • #![cfg_attr(feature = "set_panic_handler", feature(lang_items))] – gotta check, I’m sure there’s a stable way for that already
    • #![cfg_attr(feature = "with_coap_message", feature(generic_associated_types))] – optional already, because GATs are part of the coap-message API, and I still expect them to stabilize soon
    • #![feature(maybe_uninit_extra)] – gotta check, maybe that’s only used in some wrappers that are not always built. it’s probably more about idiomatics
    • #![feature(type_alias_impl_trait)] – for Args IntoIterator (and also some CoAP stuff), can be made conditional on the subsystems that actually use it
    • #![feature(const_fn_trait_bound)] – should only be used the shell
    • #![feature(const_fn_fn_ptr_basics)] – coming up in SAUL, can be made conditional

So it’s some effort, and I’d appreciate not doing it alone, but it sounds doable at least for some platforms and applications.

(And then we could go fetch that check mark on https://arewertosyet.com/ )

What this list was missing is nightly features in dependencies. coap-message is an obvious one (but not essential); of cstr-core a nightly feature is used that gives some const properties; for example, it allows having a const BOARD: &'static str that allows const-based per-board decisions.

For both, I think that they can be disabled with little loss of functionality; possibly, riot-wrappers would gain a stable feature that disables some APIs that can not be done on stable yet (like the aforementioned BOARDS const).

1 Like

Achieving buildability on stable is actually really within grasp:

There are stable-rust branches for sys and wrappers now that go most of the way – at least for the tested cases; there might still be several uses of the feature that just didn’t get pulled in in my tests (and some CI red lights just indicate it found some of that). A large part is lifted by migration away from llvm_asm!.

On native, nightly might be around for some more time, because it needs the lang_items feature – but being able to use stable on the actual targets would already be a big win.

The last feature I had to keep enabled on my test in rust-hello-world was the never_type feature (tested using RUSTFLAGS="-Zallow-features=never_type" make all BOARD=particle-xenon). That’s just a lot of API change all around riot-wrappers, in places where nobody notices the change but it’s still there (signatures changing from -> Result<..., !> to -> Result<..., Infallible>, both of which eliminate code of any formal .unwrap() or match-on-error branch). Boring footwork for another day, and possible to be coordinated with an API bump.

… and of course I’m doing all tests on nightly so far, because while the asm! macro is stable now, that’s only in nightly so far, and will take until 1.59 (~12 weeks from now, and provided nothing insurmountable comes up that makes it be reverted) to be on stable.

… and that doesn’t fix the unstable-only properties of optional dependencies used when, say, CoAP is added, but that’s really another issue.

2 Likes

I’m cheering from the side lines, but I’m finding that I’m super lost as to what the issues are. I’m feeling like an old dog, not even knowing which tricks are new.

GO! Christian! GO!

1 Like