From 26a8d0d18a0cccadfb1dcb49f2f7d44570987c37 Mon Sep 17 00:00:00 2001 From: Jannik Beyerstedt Date: Sat, 20 Jun 2026 20:01:31 +0200 Subject: [PATCH] main: Make `critical_section`s as short as possible --- src/main.rs | 143 ++++++++++++++++++++++++++++------------------------ 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/src/main.rs b/src/main.rs index f5766fc..76afcb4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -162,25 +162,32 @@ async fn main(spawner: Spawner) -> ! { let mut state = applogic::State::new(); loop { - embassy_time::Timer::after(embassy_time::Duration::from_millis(5)).await; + embassy_time::Timer::after(embassy_time::Duration::from_millis(1)).await; #[cfg(feature = "gnss")] - critical_section::with(|cs| { - let gnss_update_ref = GNSS_UPDATE.borrow(cs); + { + let mut new_position = false; + critical_section::with(|cs| { + let gnss_update_ref = GNSS_UPDATE.borrow(cs); - if let Some(fix) = gnss_update_ref.replace(None) { - let prev_state = state.initialized(); - state.update_with_gpsfix(&fix); + if let Some(fix) = gnss_update_ref.replace(None) { + let prev_state = state.initialized(); + state.update_with_gpsfix(&fix); - if prev_state != state.initialized() { - let _ = screen::clear(&mut display).inspect_err(log_screen_error); + if prev_state != state.initialized() { + let _ = screen::clear(&mut display).inspect_err(log_screen_error); + } + + new_position = true; } + }); - if fix.get_timestamp().is_some() { - info!("{}", state.print_fix()); + if new_position { + info!("{}", state.print_fix()); - // run GLOSA algorithm - #[cfg(feature = "spat")] + // run GLOSA algorithm + #[cfg(feature = "spat")] + { let signal_groups = state.run_glosa(); for sig in &signal_groups { @@ -196,69 +203,73 @@ async fn main(spawner: Spawner) -> ! { .inspect_err(log_screen_error); } } - }); + } + let mut new_data = None; critical_section::with(|cs| { let queue_rc = WIFI_RX_QUEUE.borrow(cs).borrow(); // unwrap is fine b/c we stored something in it before let queue = queue_rc.as_ref().unwrap(); if let Some(data) = queue.pop() { - match c_its_parser::de::decode(&data, c_its_parser::Headers::IEEE802LlcGnBtp) { - Ok(msg) => { - use c_its_parser::ItsMessage; - use c_its_parser::standards::extensions::ItsMessageId; - - debug!("Got new {:?} message", ItsMessageId::from(&msg)); - - match msg { - #[cfg(feature = "spat")] - ItsMessage::Mapem { - geonetworking: _, - transport: _, - etsi, - } => state.handle_mapem(&etsi), - #[cfg(feature = "spat")] - ItsMessage::Spatem { - geonetworking: _, - transport: _, - etsi, - } => { - if state.initialized() { - state.handle_spatem(&etsi); - } - } - - #[cfg(feature = "cam")] - ItsMessage::Cam { - geonetworking: _, - transport: _, - etsi, - } => applogic::cam::handle_cam(&etsi), - - #[cfg(feature = "denm")] - ItsMessage::DenmV2 { - geonetworking: _, - transport: _, - etsi, - } => applogic::denm::handle_denm(&etsi), - #[cfg(feature = "denm")] - ItsMessage::DenmV1 { - geonetworking: _, - transport: _, - etsi: _, - } => { - // irrelevant since all received DENMs should be parsed as v2 - } - } - } - Err(err) => { - // will give false-positives when a message is received which wasn't enabled - debug!("Failed to parse V2X message: {err}"); - } - } + new_data = Some(data); } }); + if let Some(data) = new_data { + match c_its_parser::de::decode(&data, c_its_parser::Headers::IEEE802LlcGnBtp) { + Ok(msg) => { + use c_its_parser::ItsMessage; + use c_its_parser::standards::extensions::ItsMessageId; + + debug!("Got new {:?} message", ItsMessageId::from(&msg)); + + match msg { + #[cfg(feature = "spat")] + ItsMessage::Mapem { + geonetworking: _, + transport: _, + etsi, + } => state.handle_mapem(&etsi), + #[cfg(feature = "spat")] + ItsMessage::Spatem { + geonetworking: _, + transport: _, + etsi, + } => { + if state.initialized() { + state.handle_spatem(&etsi); + } + } + + #[cfg(feature = "cam")] + ItsMessage::Cam { + geonetworking: _, + transport: _, + etsi, + } => applogic::cam::handle_cam(&etsi), + + #[cfg(feature = "denm")] + ItsMessage::DenmV2 { + geonetworking: _, + transport: _, + etsi, + } => applogic::denm::handle_denm(&etsi), + #[cfg(feature = "denm")] + ItsMessage::DenmV1 { + geonetworking: _, + transport: _, + etsi: _, + } => { + // irrelevant since all received DENMs should be parsed as v2 + } + } + } + Err(err) => { + // will give false-positives when a message is received which wasn't enabled + debug!("Failed to parse V2X message: {err}"); + } + } + } // maintenance state.prune();