logoalt Hacker News

carlkcarlkyesterday at 3:06 PM1 replyview on HN

I’ve been enjoying Embassy most at the application pattern layer: long-lived device tasks that hide timing and coordination behind a small, typed async API. For example:

loop { let btn = ir.wait_for_press().await; // use btn }

Meanwhile the compiler builds the state machine for you.

I think this style is an emergent property of async + no-std that hasn’t really been collected or named yet. A lot of discussion focuses on HALs, bring-up, or executors, but less on how people structure applications once those pieces are in place.

Brad Gibson and I talked about some of these ideas in this (free) article on how Embassy shines on embedded devices: https://medium.com/@carlmkadie/how-rust-embassy-shine-on-emb...

I’ve also started an open repo to experiment with and document these patterns: https://github.com/carlkcarlk/device-kit

Would love links to other repos that use Embassy at this higher, application-oriented level.


Replies

bjackmanyesterday at 6:31 PM

This isn't just useful for high-level application logic! (If I'm catching your drift from "the compiler writes the state machines for you).

I used to write extremely low-lebel NIC firmware that was basically a big bundle of state machines. Rust wasn't ready back then but I was desperate for something like coroutines/async. I think it would have been incredibly valuable.

(There are tricks to do coroutines in C but I think they're too hacky. Also, back then we believed that RTOS threads with their own stack were too expensive, in retrospect I'm not sure we ever entirely proved that).

I may be naïve in this case but I think it would also have been super useful for the high level protocol stuff. Like: 802.11 association flows. If we could have just spun up a Tokio task for each peer, I feel the code would have been an order of magnitude smaller and simpler.

show 1 reply