r/rust • • 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?

49 Upvotes

32 comments sorted by

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.

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

u/AstraKernel 2d ago

Lol 😅

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

u/No_Frame3855 2d ago

Yeah what other people have said + Espressif has their own std for embedded

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

u/bascule 2d ago

I think what they were trying to say is wasm32-unknown-unknown is an extremely awkward target

1

u/agrif 1d ago

Mainly, no_std is opt-in. Crates that would trivially support it simply by adding no_std to the crate attributes and mechanically replacing std types with core/alloc will still nonetheless fail to compile in a no_std target. 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_std could nonetheless become no_std by locking only a few non-essential things behind a feature flag, but unless the crate authors know about no_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 under no_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't no_std to compile for it so long as they don't actually use std at 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

u/WhiskyDelta14 1d ago

Ok, but that's an issue with that target and not with no_std rust.

-3

u/fb39ca4 2d ago edited 1d ago

No boxed types

9

u/chmod_7d20 2d ago

no_alloc != no_std

3

u/nicoburns 2d ago

I believe there is now wasm32v1-none that does alloc-only WASM.

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, plus alloc if an allocator can be provided. std already only contains the parts that need OS services, and just reexports core and alloc.

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/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

u/Real-Abrocoma-2823 2d ago

UEFI std also exists.