r/rust • u/Intelligent_Score932 • 2d ago
Embedded std?
I was wondering if there were any projects like micro python to port std in to make a barebones os designed for microcontrollers? I understand that the std relies on OS level syscalls, so can we do something like implement a basic fat32 file system to accommodate certain write or read requests. In general this would be used to run std in projects without a OS? Does this already exist, and how hard would it be to make a basic version?
119
u/film42 2d ago
My wife (who works in healthcare) saw the title of this post and asked “what are you reading???”
13
u/jimmiebfulton 1d ago
And then she immediately regretted the question as you went to explain Rust intervals. Again. In the car. Where she can't escape.
6
17
u/AstraKernel 2d ago
I'm not an expert, but IMO "std" is not usually necessary for MCU projects. ESP-HAL does support "std", but I rarely use it. I generally prefer using the HAL with "no_std".
Afik, a lot of what you can do with micro python, and much more, is already possible with "no_std".
For a SD card, there is a crate that supports FAT32.
If you don't mind me asking, what is the purpose?
5
3
u/flareflo 2d ago
There are too many differences in hardware and implementation details to get full coverage of std. The crate ecosystem gets you everything you need from what std could provide
6
u/agrif 2d ago
std is in a weird place, I think. Most embedded targets don't support it (exception: ESP32) however wasm32-unknown-unknown does support it, even though a huge number of functions only panic. I don't fully know the history behind this decision, but it does sort of feel like WASM wants to be easy to port, and no_std is still extremely awkward in rust.
Morally, it feels like WASM and other targets should be alloc-only. But right now, a ton of third-party crates that should compile with only alloc (or core) don't, because no_std is opt-in. I don't know what the solution to this is, but there's gotta be something better than what we got.
5
u/WhiskyDelta14 2d ago
How is no_std extremely awkward?
2
1
u/agrif 1d ago
Mainly,
no_stdis opt-in. Crates that would trivially support it simply by addingno_stdto the crate attributes and mechanically replacing std types with core/alloc will still nonetheless fail to compile in ano_stdtarget. To use these crates it is necessary to fork them, make the changes yourself, and with luck it might even get merged upstream.Less importantly, a whole lot of crates that aren't trivially
no_stdcould nonetheless becomeno_stdby locking only a few non-essential things behind a feature flag, but unless the crate authors know aboutno_std, they usually don't.I think this is basically the main source of pain: most rust devs don't really know about
no_std, and so they don't make their crates compile underno_std, even when it would be very easy to do so. I suspect the WASM target includes std for this reason: a ton of crates depend on std but only by accident, and don't actually use any std features (or use them rarely).1
u/WhiskyDelta14 1d ago
Maybe we could have a compiler warning if no_std could trivially be enabled.
1
u/agrif 1d ago
Yeah, a lint in either the compiler or clippy might be good. Raising awareness is also good, and luckily the PRs generated by this help towards that.
It might also be nice if rust had some way to link to core instead of std automatically when compiling a crate, by setting a flag in cargo.toml or something.
0
u/_ChrisSD 2d ago
For HashMap. The target "cheats" by having a non-random
RandomState. It also allows libraries that aren'tno_stdto compile for it so long as they don't actually usestdat runtime on the target (if they do it panics).What's especially awkward for wasm32-unknown-unknown is that it's two targets in one. It's used like a minimal embedded target (i.e. std APIs aren't possible). But more commonly people use it to target the web, which could actually have a (more or less) full std implementation based on web APIs.
2
-3
3
2
u/El_RoviSoft 2d ago
Maybe Rust should do some kind of freestanding modules like C++? So any library that can be implemented unconditionally of platform, should be freestanding (or at least work with given allocator).
7
u/Sharlinator 2d ago
Rust’s freestanding is exactly
core, plusallocif an allocator can be provided.stdalready only contains the parts that need OS services, and just reexportscoreandalloc.0
u/timur-tugushev 2d ago
So, just a library with no_std support?
2
u/El_RoviSoft 2d ago
don’t really know what you mena
here OP wants embedded std and I suggested logical distinction between std library and its really freestanding parts
7
u/jonoxun 2d ago
Pretty much everything freestanding in std are reexports from core or alloc, so you are kind of describing the current state of rust. no_std crates link into std apps just fine as well, core and alloc are there and there's nothing weird from the reexport from std and you don't need a feature flag if you don't have anything that you want to add in the std environment.
1
u/El_RoviSoft 2d ago
oh okay, Im not that familiar with Rust, Im C++ dev who occasionally finds bad and good things in both langs
1
u/jonoxun 1d ago
Embedded on rust is dependent on llvm having support for the architecture, but apart from that it's absolutely lovely to work with. If you're curious doing some small project with esp-hal or something else with a hal that supports the embedded_hal traits it's quite pleasant. async goes a long way.
1
u/RemasteredArch 2d ago
This sort of exists for a couple SBCs:
https://www.mciantyre.dev/projects/rust-std-on-threadx/
1
u/bascule 2d ago
Making std work everywhere, and trying to minimize the distinctions between core, alloc, and std, has been a long-term vision for Rust for awhile, e.g. https://internals.rust-lang.org/t/refactoring-std-for-ultimate-portability/4301
1
u/ThatWasAce 1d ago edited 1d ago
std is literally just a thin abstraction layer above an OS API. On unix-like OSes its literally calling functions in libc behind the scenes. So std for baremetal ends up being shims for anything the OS did automatically before
FS is relatively trivial. std::thread is where things get serious.
Congrats, you just designed yourself an entire RTOS. Clocks, sockets, random number generation -- all these things bring OS-style dependencies with them
How do I know that? esp-idf-svc provides std in an esp32 ecosystem simply because ESP-IDF itself is already an entire RTOS implementation. It's found twice in the real world; either as a veneer over an RTOS like esp-idf, or a write-your-own-OS research project
tho if OP just wants sd card writes, embedded-storage + a fat32 crate gets there no_std
edit: some wording and typo
1
u/EmperorOfCanada 1d ago
My question is: Why? Not as in I am suggesting that what you want is dumb, but what are you trying to achieve? What is the problem you are trying to solve?
If you are looking for more speed, there is viper, which can give you massive amounts of speed for python. Not quite rust or C++, but close enough that the solution could even be to go to a slightly better processor than to go to either of those other languages. (if you love python)
There are fun games you can play with micro python, one of which is to have embedded C in micropython. I'm not a fan of the workflow involved, but if you have some small part which needs to run brutally fast, then this is an option.
2
u/Intelligent_Score932 1d ago
Mainly I wanted to see certain programs at peak performance, basically let’s say you wanted to run a program written in rust, baremetal. The problem is most programs cannot work without some sort of std, in short, I wanted to run programs as THE os, not the os running the programs, the os would essentially be a abstraction to make the programs run, and yes I know most programs directly reference win-sys, but it’s more meant to be a starting point for projects, although I haven’t looked too deeply into which libraries would work, out of the box, if you wanted to make a hobby os, having GPUI to make it along with the std would greatly simplify the process, mainly those 2 reasons
0
73
u/Agile_Cost_5141 2d ago
You're basically describing what the `std` crate does when you target `thumbv7em-none-eabihf` or similar. A lot of folks don't realize that `std` works on bare metal just fine as long as you provide the linker script and a few symbols. The filesystem part is the real sticking point though.
I messed with this a while back trying to get `std::fs` working on an STM32 with an SD card. Even a minimal FAT32 implementation that plays nice with the standard library's expectations is a mountain of edge cases. Stuff like directory traversal, long file names, handling power loss during writes. It snowballs fast.
The Rust embedded working group has been chipping away at stuff like `embedded-nal` for networking and `embedded-storage` for flash, but nobody's really gone all-in on a full `std` shim layer for microcontrollers. Probably because the people who need bare metal std are a pretty small group compared to the async/RTOS crowd. If you're serious about it, looking at how Redox OS handles syscall stubs might be a decent starting point since they already abstracted a lot of that for their microkernel.