File
Blob: firmware/crates/esp32-radio/src/platform/task.rs
| 1 | use crate::error::{Error, Result}; |
| 2 | #[cfg(target_os = "espidf")] |
| 3 | use esp_idf_hal::{ |
| 4 | cpu::Core, |
| 5 | task::thread::{MallocCap, ThreadSpawnConfiguration}, |
| 6 | }; |
| 7 | use std::{marker::PhantomData, rc::Rc}; |
| 8 | |
| 9 | /// Restores the creator's pthread settings after spawning a configured task. |
| 10 | #[derive(Debug)] |
| 11 | pub(crate) struct SpawnConfig { |
| 12 | #[cfg(target_os = "espidf")] |
| 13 | saved: ThreadSpawnConfiguration, |
| 14 | _task: PhantomData<Rc<()>>, |
| 15 | } |
| 16 | |
| 17 | impl SpawnConfig { |
| 18 | pub(crate) fn radio() -> Result<Self> { |
| 19 | Self::configure(2) |
| 20 | } |
| 21 | pub(crate) fn analysis() -> Result<Self> { |
| 22 | Self::configure(0) |
| 23 | } |
| 24 | pub(crate) fn metrics() -> Result<Self> { |
| 25 | Self::configure(1) |
| 26 | } |
| 27 | #[cfg(target_os = "espidf")] |
| 28 | fn configure(role: u8) -> Result<Self> { |
| 29 | let (name, stack_size, priority, core) = match role { |
| 30 | 0 => (c"analysis", 20_480, 4, Core::Core1), |
| 31 | 1 => (c"metrics", 8192, 2, Core::Core1), |
| 32 | 2 => (c"radio", 49_152, 5, Core::Core0), |
| 33 | _ => return Err(Error::new("invalid task role")), |
| 34 | }; |
| 35 | // HAL 0.46 can return a zeroed value if IDF cannot initialize pthread |
| 36 | // storage. HAL rejects priority zero; use SDK defaults in that case. |
| 37 | let saved = ThreadSpawnConfiguration::get() |
| 38 | .filter(|config| config.priority != 0) |
| 39 | .unwrap_or_default(); |
| 40 | ThreadSpawnConfiguration { |
| 41 | name: Some(name), |
| 42 | stack_size, |
| 43 | priority, |
| 44 | pin_to_core: Some(core), |
| 45 | inherit: false, |
| 46 | stack_alloc_caps: MallocCap::Internal | MallocCap::Cap8bit, |
| 47 | } |
| 48 | .set() |
| 49 | .map_err(|error| Error::native("task configuration failed", error.code()))?; |
| 50 | Ok(Self { |
| 51 | saved, |
| 52 | _task: PhantomData, |
| 53 | }) |
| 54 | } |
| 55 | |
| 56 | // Host checks compile this error-returning stub. The target build compiles |
| 57 | // the HAL path; device checks exercise task creation and configuration. |
| 58 | #[cfg(not(target_os = "espidf"))] |
| 59 | fn configure(_role: u8) -> Result<Self> { |
| 60 | Err(Error::new("task configuration requires ESP-IDF")) |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | #[cfg(target_os = "espidf")] |
| 65 | impl Drop for SpawnConfig { |
| 66 | fn drop(&mut self) { |
| 67 | self.saved.set().expect("cannot restore task configuration"); |
| 68 | } |
| 69 | } |