From f789f6ded9439680cb027192efed95379d0af564 Mon Sep 17 00:00:00 2001 From: Victoria Fischer Date: Mon, 2 Dec 2024 19:32:18 +0100 Subject: [PATCH] task: move Scheduler into a trait, define static-sized scheduler implementation, expose as a system task runner in platform --- src/main.rs | 15 ++++++--------- src/platform/esp32.rs | 20 +++++++++++--------- src/platform/mod.rs | 5 +++-- src/task.rs | 32 +++++++++++++++++++++----------- 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/main.rs b/src/main.rs index 56fa171..af45fb6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ mod mappings; mod buffers; use crate::platform::{DefaultBoard, Board}; -use crate::task::{Task, Scheduler}; +use crate::task::{FixedSizeScheduler, Scheduler}; use crate::render::{Surfaces, Renderer}; use crate::geometry::Rectangle; @@ -26,20 +26,17 @@ fn main() { log::info!("Surface implementation: {}", core::any::type_name_of_val(&output)); log::info!("Creating animations"); - let mut tasks: Vec> = vec![ + let mut animations = FixedSizeScheduler::new([ Box::new(animations::IdleTask::new(&mut surfaces)), Box::new(animations::TestPattern::new(surfaces.new_surface(&Rectangle::everything()).unwrap())), ]; - tasks.append(&mut board.system_tasks()); - tasks.push(Box::new(Renderer::new(output, surfaces))); - - let mut runner = Scheduler::new(tasks); - - log::info!("Runner ready: {:?}", runner); + let mut renderer = FixedSizeScheduler::new([Box::new(Renderer::new(output, surfaces))]); log::info!("Ready to rock and roll"); loop { - runner.tick(); + animations.tick(); + system.tick(); + renderer.tick(); } } diff --git a/src/platform/esp32.rs b/src/platform/esp32.rs index 2c63d50..655f95d 100644 --- a/src/platform/esp32.rs +++ b/src/platform/esp32.rs @@ -18,6 +18,7 @@ use rgb::Rgb; use super::Board; +use crate::task::FixedSizeScheduler; use crate::task::Task; use crate::buffers::{Pixbuf, SurfacePool}; use crate::mappings::StrideMapping; @@ -34,12 +35,14 @@ use crate::buffers::SimpleSurface as SurfaceType; pub struct Esp32Board<'a> { output: Option<::Output>, surfaces: Option>, - tasks: Option>> + sys_loop: EspSystemEventLoop, + modem: Option, } impl<'a> Board for Esp32Board<'a> { type Output = StrideOutput<[Rgb; 310], FastWs2812Esp32Rmt<'a>>; type Surfaces = SurfacePool; + type Scheduler = FixedSizeScheduler<2>; fn take() -> Self { // It is necessary to call this function once. Otherwise some patches to the runtime @@ -51,7 +54,6 @@ impl<'a> Board for Esp32Board<'a> { let peripherals = Peripherals::take().unwrap(); let sys_loop = EspSystemEventLoop::take().unwrap(); - let nvs = EspDefaultNvsPartition::take().unwrap(); let channel = peripherals.rmt.channel0; let pins = peripherals.pins; @@ -74,10 +76,6 @@ impl<'a> Board for Esp32Board<'a> { } }; - let tasks: Vec> = vec![ - Box::new(WifiTask::new(peripherals.modem, sys_loop.clone(), &nvs)), - ]; - const POWER_VOLTS : u32 = 5; const POWER_MA : u32 = 500; const MAX_POWER_MW : u32 = POWER_VOLTS * POWER_MA; @@ -92,7 +90,8 @@ impl<'a> Board for Esp32Board<'a> { Esp32Board { surfaces: Some(SurfacePool::new()), output: Some(output), - tasks: Some(tasks), + modem: Some(peripherals.modem), + sys_loop: sys_loop.clone(), } } @@ -104,8 +103,11 @@ impl<'a> Board for Esp32Board<'a> { self.surfaces.take().unwrap() } - fn system_tasks(&mut self) -> Vec> { - self.tasks.take().unwrap() + fn system_tasks(&mut self) -> Self::Scheduler { + let nvs = EspDefaultNvsPartition::take().unwrap(); + FixedSizeScheduler::new([ + Box::new(WifiTask::new(self.modem.take().unwrap(), self.sys_loop.clone(), &nvs)), + ]) } } diff --git a/src/platform/mod.rs b/src/platform/mod.rs index bf99ca8..f970bab 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -9,14 +9,15 @@ pub mod esp32; pub type DefaultBoard = esp32::Esp32Board; use crate::render::{Output, Surfaces}; -use crate::task::Task; +use crate::task::Scheduler; pub trait Board { type Output: Output; type Surfaces: Surfaces; + type Scheduler: Scheduler; fn take() -> Self; fn output(&mut self) -> Self::Output; fn surfaces(&mut self) -> Self::Surfaces; - fn system_tasks(&mut self) -> Vec>; + fn system_tasks(&mut self) -> Self::Scheduler; } \ No newline at end of file diff --git a/src/task.rs b/src/task.rs index 365c02b..928abf3 100644 --- a/src/task.rs +++ b/src/task.rs @@ -77,25 +77,35 @@ impl ScheduledTask { } #[derive(Debug)] -pub struct Scheduler { - tasks: Vec, +pub struct FixedSizeScheduler { + tasks: [Option; TASK_COUNT], } -impl Scheduler { - pub fn new(tasks: Vec>) -> Self { - let mut scheduled = Vec::new(); +impl FixedSizeScheduler { + pub fn new(tasks: [Box; TASK_COUNT]) -> Self { + let mut scheduled = [const { None }; TASK_COUNT]; + let mut idx = 0; for task in tasks { - log::info!("Scheduling task {} {:?}", task.name(), task); - scheduled.push(ScheduledTask::new(task)); + scheduled[idx] = Some(ScheduledTask::new(task)); + idx += 1; } - Scheduler { + FixedSizeScheduler { tasks: scheduled } } +} - pub fn tick(&mut self) { - for task in &mut self.tasks { - task.tick(); +impl Scheduler for FixedSizeScheduler { + fn tick(&mut self) { + for slot in &mut self.tasks { + match slot { + Some(task) => task.tick(), + _ => () + } } } } + +pub trait Scheduler { + fn tick(&mut self); +} \ No newline at end of file