Using Rust with RIOT-OS

Hey, is anyone (besides @chrysn :slight_smile: ) looking into using Rust? I gave myself a new challenge. I want to learn Rust. And to start off with a real challenge I want to learn Rust in an embedded environment, with RIOT-OS.

@chrysn created riot-examples [1] which is, I think, a good starting point. However, not everything is working for me. It works for BOARD=stm32l476g-disco but not for my SODAQ boards such as BOARD=sodaq-sara-sff. Both use the same toolchain, but for any cortexm board the build fails with that it cannot find stdio.h. I tried to understand what is happening (cargo build is a beast), used strace and more. Still I have no clue what is going on and why it fails to find stdio.h in one case but not in the other.

Thus my question: who else has tried this?

[1] https://gitlab.com/etonomy/riot-examples

2 Likes

@Kaspar is also looking into Rust + RIOT, maybe he would have an idea as well?

Can’t help you with that one because of a different issue.

This I can only recommend, Rust is awesome. :wink:

I’ve started experimenting with core written in Rust which can be used together with RIOT. The thing also makes use of @chrysn’s riot-wrappers. It is very experimental, but initial code is here. But so far it only supports the nrf52840dk.

@Kaspar can you try to just build saul_blink for some samd21 board. I want confirmation that it is not my own installation at fault.

I’m getting the same stdio.h error:

  /home/kaspar/src/riot.tmp/cpu/cortexm_common/include/cpu.h:33:10: fatal error: 'stdio.h' file not found, err: true
  thread 'main' panicked at 'Unable to generate bindings: ()', /home/kaspar/.cargo/registry/src/github.com-1ecc6299db9ec823/riot-sys-0.3.1/build.rs

This worked before, no idea what has changed.

Thanks

Let’s hope @chrysn will chime in someday :slight_smile:

My suspicion is that clang is called in the build process and that it is using the wrong set of include directories. I believe clang is used to preprocess some files, but in doing so, it should never fall back to the “system” (i.e. host version) include directories. And with strace I could see that it is doing just that.

Plus, it remains a mystery that two arm-none-eabi boards can give different result. One builds, the other one doesn’t.

Does someone know if etonomy is still active with https://gitlab.com/etonomy/riot-examples i got a PR open there for some time

AFAIK etonomy is using the underlying riot-wrappers for their product. I guess the examples don’t get as much attention because @chrysn is busy.

Sorry, missed the notification, I’ll get back to it.

@chrysn Do you have an idea why the examples don’t build for samd21 boards? (See my initial message in this thread.)

Mh, I can reproduce it (based on 2021.01 RIOT and latest HEAD (96fbfd46) of the examples); looking into it.

What I got so far:

  • It seems to be CPU core specific; I’ve only seen this on cortex-m0 and cortex-m0plus boards, which are both armv6s-m (like stk3200 or nucleo-f072rb even though they hit stdint.h first; not m3 as in stk3700).

  • When using TOOLCHAIN=llvm, the trouble goes away (except for stk3200 but it’s a ROM overflow that kills it there – haven’t tried to optimize anything there yet, but Rust’s standard string formatting is pretty heavy).

    I think I should make LLVM the recommendation for Rust-on-RIOT anyway.

Still looking for what actually causes this, but at least using LLVM should get you going again.

The whole process is quiet complicated. I got lost in all the details. Somehow I got the impression that one of the (underlying) compilation/preprocessing was done with the host environment instead of the cross-compile environment.

Doing an strace I could see /usr/include/stdio.h being used and that can never be correct for a non-native board. But like I said, it’s complicated, I could be totally wrong.

And there may even be a RIOT problem with detection the correct details of the toolchain (especially include directories).

But do you get your applications to work with TOOLCHAIN=llvm at least? (Honestly, it may be that GCC is something supporting which I’d postpone.)

The over-all situation is admittedly far from ideal. Trouble is that neither bindgen nor c2rust are particularly cross-building friendly (even tough Rust itself usually is). Maybe I’m also doing it wrong, and should (rather than trying to find the right build arguments half-on-my-own) ask the RIOT build system for the right build arguments for LLVM, apply those and trust the implied promise that no matter the toolchain, the C ABI is upheld and they can link interchangably.

Knowing whether the problem dissolves for you too with TOOLCHAIN=llvm would be one data point to guide that decision. (If I go the abovementioned route in the default build integrations, the GCC could then become usable again).

I can confirm that the saul_blink example works with TOOLCHAIN=llvm

1 Like

Having dug farther and farther into which CFLAGS are set why and when, I think more and more that the right way for riot-sys (or, more, the build integration) is to ask the RIOT build system for which CFLAGS would be set if building with CLANG.

Unfortunately, these are not set just in the toolchain specific includes, but at several places by checking for TOOLCHAIN. That should also solve the issues about the host stdio.h being used, because when clang is used, the makefiles pass the rigth libc to use in CFLAGS (eg. libc/newlib.mk in NEWLIB_INCLUDES).

(Really, that the libc is entangled with the compiler in the first place is a mess of its own).

The easy step is to update the examples (done), the next step is properly resolving #3.

That’s what I’m doing with RIOT-rs, just use the output of “make info-debug-variable-CFLAGS” etc.