Open dhoove opened 6 years ago
This should be quite possible now that async fully works on embedded. Here's a proof of concept from Ferrous Systems (blog post on it).
A number of things would have to change about the current single threaded executor to get this to work though. It uses Arc/Rc
and spawns a thread, whereas for embedded reference counters aren't available in core and obviously you wouldn't spawn a thread for the executor.
Perhaps a simple, separate bare bones executor would be useful?
The most basic possible executor requires 2 things that aren't available in core
:
Arc
normally, but depending on other details could be something as simple as an &'static _
(if you only want to support a single future in the lifetime of the application).Thread::{park, unpark}
normally, but some systems such as the Cortex-M series have dedicated assembly instructions that can be used for this (WFE
/SEV
).Since these details are platform specific it might be possible to have a generic executor that is capable of having concrete implementations plugged into it for them. But then the generic executor part becomes so trivial I don't see any reason to not just have platform specific executors.
- Some form of shared ownership, this is
Arc
normally, but depending on other details could be something as simple as an&'static _
(if you only want to support a single future in the lifetime of the application).
I think it's reasonable to require an allocator for a generic executor, so things like Arc
and Box
could be used in embedded (alloc crate).
- Some way to do parking/unparking of the main thread, this is
Thread::{park, unpark}
normally, but some systems such as the Cortex-M series have dedicated assembly instructions that can be used for this (WFE
/SEV
).
Agreed that this is a problem. It could be abstracted as you say, but I suppose you're right, the local_pool
executor is pretty small and trivial, maybe it does make sense to have these executors implemented elsewhere.
I created a pool based on LocalPool
which is generic over a park and an unpark function. It works very well on my cortex-m board. Creation looks like this: EmbeddedPool::new(asm::sev, asm::wfe)
.
Should I create PR to discuss it or would it be better for me to publish it in a separate crate?
Awesome! Either way, I'd be interested to take a look.
I created a PR containing my work, open for discussion! #2185
Maybe this could be integrated in some way? https://github.com/Dirbaio/static-executor
This comment in #944 gave me some hope that it would soon be possible to use a single-threaded executor with no_std. I would like to be able to use async code for embedded applications. The general-purpose asynchronous CoAP library, mentioned in #860, also sounds very interesting for newer IoT devices. Wouldn't this also require a no_std executor?