Skip to content
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

[Discussion] Rust integration in Nuttx #11907

Open
rushabhvg opened this issue Mar 13, 2024 · 29 comments
Open

[Discussion] Rust integration in Nuttx #11907

rushabhvg opened this issue Mar 13, 2024 · 29 comments

Comments

@rushabhvg
Copy link
Contributor

As a part of GSOC 2024, I wish to integrate Rust into Nuttx. For that, a new coding standard for Rust programming language will be required and there's no mention of it anywhere. Before writing any rust code, a coding standard would be required. Please give your inputs. I was able to find C coding standards at: C Coding Standard

@rushabhvg
Copy link
Contributor Author

@xiaoxiang781216 @anchao @raiden00pl Please give your suggestions.

@xiaoxiang781216
Copy link
Contributor

xiaoxiang781216 commented Mar 13, 2024

NuttX doesn't support Rust yet, that's why no Rust coding standard exist in official document. As far as I know, Rust defines an official coding standard, so I would suggest that NuttX follow this style too. @patacongo @acassis what do you thinking?

@ppisa
Copy link
Contributor

ppisa commented Mar 13, 2024

I think that it would worth to discuss Rust on NuttX with @lupyuen https://lupyuen.github.io/ . I have seen lot of useful information on his site.

@lupyuen
Copy link
Member

lupyuen commented Mar 13, 2024

Yep sure let's have a chat. I'm more into Rust Apps for NuttX, not so much Rust Kernel for NuttX. But let's talk :-)

(Linux Kernel Rust might be a good model to adopt)

@rushabhvg
Copy link
Contributor Author

Hello @lupyuen then maybe I can start with Rust Apps for Nuttx? How should we communicate?

@lupyuen
Copy link
Member

lupyuen commented Mar 13, 2024

@rushabhvg Let's discuss over email: [email protected]. I'm in Singapore (GMT+8) so my response may be slow. Thanks :-)

@acassis
Copy link
Contributor

acassis commented Mar 13, 2024

NuttX doesn't support Rust yet, that's why no Rust coding standard exist in official document. As far as I know, Rust defines an official coding standard, so I would suggest that NuttX follow this style too. @patacongo @acassis what do you thinking?

@xiaoxiang781216 you mean for Rust applications or Rust code used on kernel right? I think it makes sense because Rust developer could feel uncomfortable reading/write Rust code using NuttX Coding Style

@TimJTi
Copy link
Contributor

TimJTi commented Mar 13, 2024

Is this a suggestion that NuttX RTOS itself will move from C to Rust? Or a mix of the two? Sorry if it's a dumb question but I know nothing about rust other than what's on my car...

@patacongo
Copy link
Contributor

I would think that a mix of the two could be a maintenance problem.

@acassis
Copy link
Contributor

acassis commented Mar 13, 2024

Is this a suggestion that NuttX RTOS itself will move from C to Rust? Or a mix of the two? Sorry if it's a dumb question but I know nothing about rust other than what's on my car...

I thought exactly that when I read Xiang comments at first time, but no, he was just saying: let Rust code to use Rust coding style, that makes sense. But as Greg commented we need to figure out how to improve the maintenance to have two coding styles. Maybe just having CI checker for .c and .rs is enough, not sure

@TimJTi
Copy link
Contributor

TimJTi commented Mar 13, 2024

Is this a suggestion that NuttX RTOS itself will move from C to Rust? Or a mix of the two? Sorry if it's a dumb question but I know nothing about rust other than what's on my car...

I thought exactly that when I read Xiang comments at first time, but no, he was just saying: let Rust code to use Rust coding style, that makes sense. But as Greg commented we need to figure out how to improve the maintenance to have two coding styles. Maybe just having CI checker for .c and .rs is enough, not sure

Where would Rust code be used - approved to be used - though?

@patacongo
Copy link
Contributor

Where would Rust code be used - approved to be used - though?

It is somewhat less concerning if restricted to architecture- or board- specific logic as Alan suggested in an dev email.

Any use of use of Rust in the OS must have the support of the NuttX community. Not just the small group of people with special interests in this issue.

@cederom
Copy link
Contributor

cederom commented Mar 13, 2024

Hello @rushabhvg and thank you for your interest in NuttX RTOS :-) My suggestions for the workplan in 5 simple steps is presented below :-)

  1. Limit Rust use for APPLICATIONS ONLY and NOT THE KERNEL.
  2. Work on application layer just like other programming languages do in NuttX (i.e. existing Basic code or new ZigLang apps created by @lupyuen).
  3. Work out optional setup that will allow porting and running Rust applications on NuttX. Use most generic and well known Rust tool set for integration like [1].
  4. Create and/or Port some demo applications including peripherals use cases (i.e. UART, SPI, I2C, graphical display, audio, input, network). Note that applications should only use existing underlying RTOS drivers (i.e. Arch + Board setup with devfs+ioctl interface) and not their own drivers that would interfere with existing RTOS drivers.
  5. Create documentation on how to setup local environment for Rust build, how to setup NuttX to work with Rust, how to build a firmware with NuttX and example Rust applications, how to port new Rust applications to NuttX (including KConfig, Makefile, etc).

[1] https://github.com/rust-embedded/awesome-embedded-rust

@rushabhvg
Copy link
Contributor Author

Okay @cederom I will follow this worklplan. ANd, work with @lupyuen .

@lupyuen
Copy link
Member

lupyuen commented Mar 14, 2024

Hi All: @rushabhvg couldn't register on the NuttX Mailing List to read our thoughts about Rust. Any idea how we can troubleshoot this? Thanks :-)

@rushabhvg
Copy link
Contributor Author

I have tried creating my account through this url when I click on "Subscribe to list" button, nothing happens. Kindly guide.

@lupyuen
Copy link
Member

lupyuen commented Mar 14, 2024

Hi @rushabhvg thanks for chatting over email (and listening to my rant on Rust pros and cons :-) I suggest we begin with this:

  1. Let's build and run a simple Rust App on NuttX: https://gist.github.com/lupyuen/7be4bedc6a109b2c3d1201aee6030428
  2. If you see this error, let's discuss over email: "Can't link soft-float modules with double-float modules"
  3. Assuming our Rust App runs OK on NuttX: Let's port this LED Blinky App from C to Rust (because it demonstrates POSIX Support): https://github.com/lupyuen2/wip-pinephone-nuttx-apps/blob/nim/examples/hello/hello_main.c#L40-L85
  4. ULEDIOC_SETALL is explained here: https://lupyuen.github.io/articles/nim#blink-an-led
  5. Then we'll do the same for larger Rust Apps, hopefully we'll work out the Rust Coding Guidelines along the way. Thanks :-)

@rushabhvg
Copy link
Contributor Author

Okay thanks! @lupyuen

@acassis
Copy link
Contributor

acassis commented Mar 14, 2024

I have tried creating my account through this url when I click on "Subscribe to list" button, nothing happens. Kindly guide.

You can send a email to [email protected] and then reply the received email

@acassis
Copy link
Contributor

acassis commented Mar 14, 2024

@lupyuen I think you pointed to hello world in C, the hello world in rust is at hello_rust. But as Dan Gohman ( @sunfishcode ) commented in this Rustix presentation, the integration has some issues, the way it was done we will need a wrapper (extern "C" {} ) for all functions of NuttX. I don't know if he still available to help us, let me ping him and see.

@lupyuen
Copy link
Member

lupyuen commented Mar 15, 2024

For the record: This PR explains why we're not using Rust Crates, cargo build and Cargo.toml in NuttX: #5566

Which presents interesting challenges for Rust Apps in NuttX :-) @rushabhvg Let's document the workarounds that we used (patching of ELF Header, RUSTFLAGS=-O), I think it will be highly useful for other devs

(Might be a good topic for the upcoming NuttX Workshop!)

@lupyuen
Copy link
Member

lupyuen commented Mar 15, 2024

Some folks are wondering: Why not use the Rust Standard Library, instead of the barebones no_std? (Rust Core Library) Isn't the Rust Standard Library a lot simpler for doing Console I/O and other POSIX Operations?

  1. Traditionally when we build firmware for Embedded Devices, we use no_std: https://docs.rust-embedded.org/book/intro/no-std.html

  2. Each Embedded OS will have its own C Function for Console I/O. On NuttX: It just happens that we call the C Standard Library, because NuttX supports POSIX. On FreeRTOS: It would be a totally different C Function.

  3. NuttX is a little different from other RTOS because it's compatible with POSIX. In theory, Rust Standard Library could run on NuttX, thanks to POSIX. But it needs work.

  4. Rustix Project is working on supporting Rust Standard Library on NuttX. But it seems to have stalled:

    https://www.reddit.com/r/rust/comments/zfwaqf/integrating_rustix_on_nuttx/

    https://github.com/bytecodealliance/rustix/tree/nuttx

    https://www.youtube.com/watch?v=JTJW6kOqf9I

  5. In any case, running Rust Standard Library on Embedded Devices will have impact on Memory Size and Real-Time Performance. Consider Rust on ESP32: It supports Rust Standard Library as well as no_std: https://docs.esp-rs.org/book/overview/using-the-standard-library.html

    ESP32 Rust Standard Library is not recommended if we need Small Memory Footprint, Direct Hardware Control and Real-Time Performance: https://docs.esp-rs.org/book/overview/using-the-core-library.html

  6. So for NuttX: We should probably provide Minimal Rust Wrappers around the POSIX Functions that we actually need, instead of supporting the entire Rust Standard Library. If we look at LED Blinky: We'll need open(), close(), ioctl(), sleep(), ...

    The Rust Wrappers should allow Strings and Pointers to be passed safely to/from NuttX. Maybe the Rustix Project has something we can borrow: https://github.com/bytecodealliance/rustix/tree/nuttx

@acassis
Copy link
Contributor

acassis commented Mar 15, 2024

@lupyuen thank you for summarize it very well. Let's ping @ptka he could be interested to see this progress and hopeful help us on this effort.

@lupyuen
Copy link
Member

lupyuen commented Mar 16, 2024

FYI @rushabhvg Linux Kernel has Coding Guidelines and Templates that might be helpful:

@lupyuen
Copy link
Member

lupyuen commented Mar 17, 2024

FYI: Zephyr OS is also working on supporting Rust Apps and Rust Drivers: zephyrproject-rtos/zephyr#65837

@patacongo
Copy link
Contributor

patacongo commented Mar 17, 2024

@lupyuen I have a question that maybe you can answer. Everything that I have read says that Rust runs "on top of an OS". I can't find the exhaustive list of OS interfaces required by Rust. Such a thing must exist somewhere to support porting to other OSs.

I checked a couple of specific interfaces. malloc(), for example, seems to be required by Rust.

In KERNEL and PROTECTED build modes, malloc() is not available in the kernel. kmm_malloc() must be used instead to allocate from the kernel heap. So I suppose that in these modes you would need wrappers around all of the application OS functions required by Rust to use the internal OS functions: To fix functionality in some cases. What about cancellation points and returned errno values? There is no errno within the OS.

Even in the FLAT build, OS code avoids calling application interfaces directly to eliminate spurious cancellation points and clobbering the per-task errno value.

@lupyuen
Copy link
Member

lupyuen commented Mar 17, 2024

Hi @patacongo :-) There are 2 "flavours" of Rust, depending on the Rust Libraries that we use:

  • Rust Standard Library: This is used by most Rust Apps on desktops and servers. Supports Heap Memory and the Rust Equivalent of POSIX Calls.
  • Rust Core Library (no_std): Barebones Rust Library that runs on Bare Metal, used by Rust Embedded Apps. Calls minimal libc functions, doesn't support Heap Memory and POSIX.

The malloc() that you mentioned: It's called by the Rust Standard Library. (Like this)

For Kernel Dev (like Linux): We'll use the Rust Core Library. Which doesn't support Heap Memory and doesn't need malloc().

But most Kernel Drivers will need Kernel Heap. That's why Linux Kernel also supports the alloc Rust Library / Crate. To implement Rust alloc, Linux Kernel calls krealloc() to allocate Kernel Heap. (Like this)

For NuttX Kernel: We'll implement Rust alloc by calling kmm_malloc().

Since we're calling Rust Core Library in the Kernel, we won't touch any POSIX Application Interfaces. So if we need to support the Kernel Equivalent of Cancellation Points and Errno, we'll have to build the Rust Library ourselves. (Here's the Rust Library for Linux Kernel)

@patacongo
Copy link
Contributor

Since we're calling Rust Core Library in the Kernel, we won't touch any POSIX Application Interfaces. So if we need to support the Kernel Equivalent of Cancellation Points and Errno, we'll have to build the Rust Library ourselves

No, I meant the opposite. The kernel should never initiate a cancellation point and should never modify the errno. My concern was that any application interfaces called from a kernel-embedded, run-time library might do just that.

Related: NuttX does not support shared libraries in these build modes. This means that there might be multiple copies of whatever necessary run-time support is needed in each user and kernel address space. The C libraries really have this same problem at present.

@acassis
Copy link
Contributor

acassis commented Mar 20, 2024

That is an interesting interview with Linus Torvalds about Rust: https://www.youtube.com/watch?v=YyRVOGxRKLg

Although he doesn't program in Rust, he seems to agree it is an important addition to Linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants