zephyr: Add
blockingmodule with async support (#173)This adds a new module which makes it very easy to offload blocking Zephyr calls onto a worker thread pool and then
awaitthem from an async executor thread without stalling the entire executor.The motivation behind this is that, while many Zephyr subsystems do provide an async interface, some do not (such as fuel gauges), so this allows you to, for example, read from a fuel gauge in an async task without stalling the executor.
Of course, there is always a cost of having to setup a worker pool and offloading work to it in terms of increased memory size and context-switching price, so this is intended to be used simply when you don’t have an alternative. But this module handles all the details and provides a simple abstraction making it easy for users who do need this.
Originally had considered using the Zephyr-native P4WQ for the thread pool, but it turns out this won’t actually work with blocking calls (see: https://github.com/zephyrproject-rtos/zephyr/pull/92462). Additionally, using a Zephyr-native workqueue doesn’t buy us much either since we still need to manage multiple workqueues and the interface for submitting work isn’t that helpful here either.
So, in addition to providing the async interface, this also includes simple worker thread pool management all within Rust and can be tweaked via Kconfig.
Some shortcomings:
- This is NOT priority-aware (unlike P4WQ), so in the near-future would like to add that functionality, but want to keep this initial PR short for now.
- This uses an implementation that does not require alloc (since in the Discord it seems @d3zd3z mentioned he would prefer to move away from alloc-only implementations in this repo) but I want to provide an alloc alternative (if the user enables it) that could make it a bit easier to not have to tweak a few Kconfig knobs.
A few other notes:
- Had to tweak queue to provide a
removemethod and had to tweaklib.rsto reexport thezephyrcrate explicitly as its own name to be able to usezephyr::threadinternally (though a better approach might be to modify the proc macro to not have this be necessary)- The module is also gated behind
async-driverswhich is kind of confusing since this isn’t necessarily only used by drivers, but theembassy-syncdep is gated behindasync-driverswhich this uses (so alternatively could just always bring inembassy-sync)
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802047560号