You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Embassy "The next-generation framework for embedded applications. Write safe, correct and energy-efficient embedded code faster, using the Rust programming language, its async facilities, and the Embassy libraries."
This framework primarily provides extensive async support for various platforms. It can be used natively (bare metal), with an executor that schedules async execution on a single thread, or other executors that run in IRQ mode. There is also support for the RTIC framework.
Adding support so that this framework can be used within Zephyr is not particularly difficult. In fact, the single thread executor just works, as is, on top of Zephyr. If run from the lowest-priority thread, it is perfectly usable, although it might inhibit sleep in some cases. To be truly useful, there needs to be an embassy-time-driver implementation for Zephyr so that delaying and periodic intervals will work.
It also would not be that difficult to implement a specific variant of the embassy executor that would use Zephyr's thread primitives and allow an executor to be run per thread in Zephyr. This would allow multiple async tasks to run within a single Zephyr thread.
The main issue is that a traditional rust async executor will be incompatible with the scheduling primitives within Zephyr. However, embassy provides async versions of these primitives that will work fine within Zephyr. Driver callbacks can use the non-blocking "wake" versions of these primitives to allow coordination between Zephyr drivers and frameworks and the Embassy primitives.
To implement this, this proposes a few features:
embassy-time-driver: Enabling this within the zephyr crate will provide a time driver to Embassy so that the facilities in embassy-time can be used freely within Zephyr
embassy-executor: Enabling this will provide an executor, using Embassy-executor, that will run tasks on a single Zephyr thread (as a function that never returns). It is possible to run multiple of these, specifically on threads of different priorities).
Conflicts
The embassy-executor feature will be mutually exclusive with the executor-thread and executor-interrupt features on Embassy-executor. In addition, the _async operations on Zephyr primitives are incompatible with this executor. It might be reasonable to conditionalize these such that they are not available if the embassy-executor is chosen, but it is still possible for an app to bring in the embassy-thread executor.
Enabling executor-thread on embassy requires the architecture to be specified. This can be done in the Cargo.toml, but will make for a package that will only work on a single architecture. If useful, the CMake file could be extended to set these features as needed to allow multiple targets to be used.
Benefits
Within zephyr::kio and zephyr::work, the Zephyr crate provides an async executor that uses Rust work queues. This provides a few benefits:
This async support works with Zephyr's sync primitives (at least Semaphore, and Queue).
This code otherwise works more tightly with Zephyr operations.
and some disadvantages:
There is effectively double scheduling overhead, the operations generally invoke both the work queue scheduler and the Zephyr thread scheduler together.
The embassy-executor (embassy-thread) provides very low scheduling overhead for async tasks, but only supports running in a single Zephyr thread. The executor that this issue will provide will run on Zephyr threads. The additional overhead will be low, but non-zero. Waking async tasks will require a call into k_thread_resume, which if the thread is running, is a quick check, but does have a spin lock, and if it has to wake the thread does require a reschedule within Zephyr. However, this now allows these async managing threads to coexist with other threads within Zephyr, rather than just requiring it to be run on the lowest priority thread.
The text was updated successfully, but these errors were encountered:
Embassy "The next-generation framework for embedded applications. Write safe, correct and energy-efficient embedded code faster, using the Rust programming language, its async facilities, and the Embassy libraries."
This framework primarily provides extensive async support for various platforms. It can be used natively (bare metal), with an executor that schedules async execution on a single thread, or other executors that run in IRQ mode. There is also support for the RTIC framework.
Adding support so that this framework can be used within Zephyr is not particularly difficult. In fact, the single thread executor just works, as is, on top of Zephyr. If run from the lowest-priority thread, it is perfectly usable, although it might inhibit sleep in some cases. To be truly useful, there needs to be an
embassy-time-driver
implementation for Zephyr so that delaying and periodic intervals will work.It also would not be that difficult to implement a specific variant of the embassy executor that would use Zephyr's thread primitives and allow an executor to be run per thread in Zephyr. This would allow multiple async tasks to run within a single Zephyr thread.
The main issue is that a traditional rust async executor will be incompatible with the scheduling primitives within Zephyr. However, embassy provides async versions of these primitives that will work fine within Zephyr. Driver callbacks can use the non-blocking "wake" versions of these primitives to allow coordination between Zephyr drivers and frameworks and the Embassy primitives.
To implement this, this proposes a few features:
embassy-time-driver
: Enabling this within thezephyr
crate will provide a time driver to Embassy so that the facilities inembassy-time
can be used freely within Zephyrembassy-executor
: Enabling this will provide an executor, using Embassy-executor, that will run tasks on a single Zephyr thread (as a function that never returns). It is possible to run multiple of these, specifically on threads of different priorities).Conflicts
The
embassy-executor
feature will be mutually exclusive with theexecutor-thread
andexecutor-interrupt
features on Embassy-executor. In addition, the_async
operations on Zephyr primitives are incompatible with this executor. It might be reasonable to conditionalize these such that they are not available if theembassy-executor
is chosen, but it is still possible for an app to bring in the embassy-thread executor.Enabling
executor-thread
on embassy requires the architecture to be specified. This can be done in the Cargo.toml, but will make for a package that will only work on a single architecture. If useful, the CMake file could be extended to set these features as needed to allow multiple targets to be used.Benefits
Within
zephyr::kio
andzephyr::work
, the Zephyr crate provides an async executor that uses Rust work queues. This provides a few benefits:and some disadvantages:
The embassy-executor (embassy-thread) provides very low scheduling overhead for async tasks, but only supports running in a single Zephyr thread. The executor that this issue will provide will run on Zephyr threads. The additional overhead will be low, but non-zero. Waking async tasks will require a call into
k_thread_resume
, which if the thread is running, is a quick check, but does have a spin lock, and if it has to wake the thread does require a reschedule within Zephyr. However, this now allows these async managing threads to coexist with other threads within Zephyr, rather than just requiring it to be run on the lowest priority thread.The text was updated successfully, but these errors were encountered: