3 ms·
I'm curious why you don't like it for embedded - embassy has been an absolute delight for me thus far, and my primary complaint about it is just that it doesn't
by dgacmu 3y ago
I'm curious why you don't like it for embedded - embassy has been an absolute delight for me thus far, and my primary complaint about it is just that it doesn't have the breadth of hardware support (yet?). It's been the thing that has redeemed Rust async for me, as otherwise, I tend to find the tension the author notes frustrating as well.
- steveklabnik 3y agoI am pro async Rust, but we don't use async in our embedded projects at Oxide. This is because of specific design constraints and goals: https://hubris.oxide.computer/reference/#_why_synchronous https://hubris.oxide.computer/reference/#_why_synchronous That being said, I am also a fan of embassy when you have different design constraints and goals, and consider the fact that is is able to exist and be successful is a massive testament to the design of async Rust. (We also use async Rust heavily further up the stack, and have some issues with it, but they tend to be disjoint from the way that this is talked about online.)
- dgacmu 3y agoOddly, I agree with you - but I think I may be approaching it differently. I use async as a mechanism to be able to have clearly-defined "tasks" in an embedded context, where tasks have straight-line code that handles something. I have most of the interaction between tasks be synchronous; in the case of embassy, the thing it brings is that it manages that otherwise-spaghetti-feeling mix of state machines in an easy-to-read kind of way. Example from a current side project, since it's not work-encumbered: A wifi-enabled clock light for my 5yo. It has a task that sits there and every hour pings an SNTP server, updating a (mutex-protected) global with the time state. It has another task that listens for a telnet session for various control signals - which also updates a mutex-protected global config state. And it has a task that spins doing LED effects. With embassy/async, I can write each of those as a separate task, without paying much attention to what gets invoked by interrupt handlers. (This particular one is an rp2040, but I use it on stm-based systems as well). I feel like this is kind of analogous to the discussion of threads-vs-events as a mechanism for structuring code vs. threads as a mechanism for achieving parallelism. :-) Edited to add: Or, perhaps an alternative view of what I'm doing is that I'm using the embassy runtime as a really lightweight alternative to an RTOS, since I mostly haven't met an RTOS I don't want to throw across the room. An argument against what I'm saying here is, "well, use Hubris as your embedded OS and then you can have tasks and they can be synchronous" - which seems entirely fair.
- steveklabnik 3y ago> I use async as a mechanism to be able to have clearly-defined "tasks" in an embedded context This is also a good design! The primary designer of Hubris also has a project that works like this: https://github.com/cbiffle/lilos https://github.com/cbiffle/lilos
- the__alchemist 3y agoWhat I like about Embassy is the Metapac, and less reliance on generics and typestates than predecessors. My complaint is I don't find the async ergonomics intuitive; it feels like a layer of misdirection. And, the viral character.