Open rushabhvg opened 4 months ago
@xiaoxiang781216 @anchao @raiden00pl Please give your suggestions.
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?
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.
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)
Hello @lupyuen then maybe I can start with Rust Apps for Nuttx? How should we communicate?
@rushabhvg Let's discuss over email: luppy@appkaki.com. I'm in Singapore (GMT+8) so my response may be slow. Thanks :-)
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
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 would think that a mix of the two could be a maintenance problem.
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
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?
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.
Hello @rushabhvg and thank you for your interest in NuttX RTOS :-) My suggestions for the workplan in 5 simple steps is presented below :-)
Okay @cederom I will follow this worklplan. ANd, work with @lupyuen .
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 :-)
I have tried creating my account through this url when I click on "Subscribe to list" button, nothing happens. Kindly guide.
Hi @rushabhvg thanks for chatting over email (and listening to my rant on Rust pros and cons :-) I suggest we begin with this:
Okay thanks! @lupyuen
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 dev-subscribe@nuttx.apache.org and then reply the received email
@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.
For the record: This PR explains why we're not using Rust Crates, cargo build
and Cargo.toml
in NuttX: https://github.com/apache/nuttx/pull/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!)
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?
Traditionally when we build firmware for Embedded Devices, we use no_std: https://docs.rust-embedded.org/book/intro/no-std.html
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.
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.
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/
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
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
@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.
FYI @rushabhvg Linux Kernel has Coding Guidelines and Templates that might be helpful:
FYI: Zephyr OS is also working on supporting Rust Apps and Rust Drivers: https://github.com/zephyrproject-rtos/zephyr/issues/65837
@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.
Hi @patacongo :-) There are 2 "flavours" of Rust, depending on the Rust Libraries that we use:
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)
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.
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.
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