Expand description
An RTOS (Real-Time Operating System) implementation for esp-hal.
This crate provides the runtime necessary to run async code on top of esp-hal,
and implements the necessary capabilities (threads, queues, etc.) required by esp-radio.
§Setup
This crate requires an esp-hal timer, as well as the FROM_CPU0 software interrupt to
operate, and needs to be started like so:
use esp_hal::timer::timg::TimerGroup;
let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_rtos::start(timg0.timer0, peripherals.FROM_CPU_INTR0);
// Optionally, start the scheduler on the second core
use static_cell::ConstStaticCell;
use esp_hal::system::Stack;
static STACK: ConstStaticCell<Stack<8192>> = ConstStaticCell::new(Stack::new());
esp_rtos::start_second_core(
peripherals.CPU_CTRL,
peripherals.FROM_CPU_INTR1,
STACK.take(),
|| {}, // Second core's main function.
);
// You can now start esp-radio:
// let esp_radio_controller = esp_radio::init().unwrap();To write async code, enable the embassy feature, and make the main function async.
This will create a thread-mode executor on the main thread. Note that, to create async tasks, you will need
the task macro from the embassy-executor crate. Do NOT enable any of the arch-* features on embassy-executor.
The scheduler can also run on the second core alone, which keeps the first core free for bare-metal
code. See start_on_second_core_only for that configuration and its restrictions.
§Automatic Light Sleep (experimental)
When enabled, the CPU will automatically enter light sleep mode when there are no tasks to run, and wake up when a task is ready to run. This can help reduce power consumption.
Because waking up from automatic light sleep can increase latency, the minimum expected idle time
can be configured using ESP_RTOS_CONFIG_LIGHT_SLEEP_MIN_US.
To enable automatic light sleep, call the sleep::configure function and pass the
idle hook from the returned Sleep object to start_with_idle_hook.
To prevent the CPU from entering light sleep, take a WakeLock. Drop the lock when you are done
with the critical code.
⚠️ If you are using bare-metal code on the second core (i.e. the second core is
not managed by the RTOS), make sure to take a WakeLock, otherwise the automatic
light sleep may cause unexpected behavior.
§Example
#![no_std]
use esp_hal::timer::timg::TimerGroup;
let p = esp_hal::init(esp_hal::Config::default());
let timg0 = TimerGroup::new(p.TIMG0);
let sleep = esp_rtos::sleep::configure(p.LPWR);
esp_rtos::start_with_idle_hook(
timg0.timer0,
p.FROM_CPU_INTR0,
sleep.light_sleep_hook,
);§Additional configuration
| Option | Stability | Default value | Allowed values |
|---|---|---|---|
ESP_RTOS_CONFIG_TICK_RATE_HZ Tick rate of the task scheduler in Hertz | ⚠️ Unstable | 100 | Positive integer |
ESP_RTOS_CONFIG_LIGHT_SLEEP_MIN_US Minimum predicted sleep duration, in microseconds, required for the auto light-sleep idle hook to enter light sleep instead of WFI. | ⚠️ Unstable | 1000 | Positive integer |
ESP_RTOS_CONFIG_SW_TASK_OVERFLOW_DETECTION Enable software-based stack overflow detection. The stack guard value and offset is based on esp-hal configuration. | ⚠️ Unstable | false | |
ESP_RTOS_CONFIG_STACK_POINTER_RANGE_CHECK Enable range-check based stack overflow detection. | ⚠️ Unstable | true | |
ESP_RTOS_CONFIG_HW_TASK_OVERFLOW_DETECTION Enable hardware-based stack overflow detection. The stack watermark is based on the esp-hal stack-guard-offset configuration. | ⚠️ Unstable | true | |
ESP_RTOS_CONFIG_RADIO_TIMER_THREAD_PRIORITY Priority of the timer thread serving esp-radio. | ⚠️ Unstable | 2 | Integer in range 2..28 |
§Feature Flags
-
embassy— Enable embassy integration (time driver and executors). -
esp-radio— Enable esp-radio support. -
esp-alloc— Enable the use of theesp-alloccrate for dynamic memory allocation.Memory allocation is required by
esp-radio. If you choose to not enable this feature, you need to provide implementations for the following functions:pub extern "C" fn malloc_internal(size: usize) -> *mut u8pub extern "C" fn free_internal(ptr: *mut u8)
Note that the untyped nature of the allocator functions means that esp-alloc is likely the more memory efficient option.
-
rtos-trace— Enablertos-tracesupport.
§Chip selection
One of the following features must be enabled to select the target chip:
esp32esp32c2esp32c3esp32c5esp32c6esp32c61esp32h2esp32p4esp32s2esp32s3esp32s31
§Logging Feature Flags
log-04— Enable logging output using version 0.4 of thelogcrate.defmt— Enable logging output usingdefmtand implementdefmt::Formaton certain types.
Modules§
Structs§
- Current
Thread Handle - A handle to the current thread.
Traits§
- Timer
Source - Timers that can be used as time drivers.
Functions§
- rearm_
alarm - Rearms the alarm timer.
- start
- Starts the scheduler.
- start_
on_ second_ core_ only multi_core - Starts the scheduler on the second CPU core only.
- start_
second_ core multi_core - Starts the scheduler on the second CPU core.
- start_
second_ core_ with_ stack_ guard_ offset multi_core - Starts the scheduler on the second CPU core.
- start_
with_ idle_ hook - Starts the scheduler, with a custom idle hook.
Attribute Macros§
- main
embassy - Attribute to declare the entry point of the program.