diff options
Diffstat (limited to 'macros/src/codegen/pre_init.rs')
-rw-r--r-- | macros/src/codegen/pre_init.rs | 108 |
1 files changed, 25 insertions, 83 deletions
diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index f89dec96..9c5f35ec 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -5,75 +5,52 @@ use rtic_syntax::ast::App; use crate::{analyze::Analysis, check::Extra, codegen::util}; /// Generates code that runs before `#[init]` -pub fn codegen( - core: u8, - app: &App, - analysis: &Analysis, - extra: &Extra, -) -> ( - // `const_app_pre_init` -- `static` variables for barriers - Vec<TokenStream2>, - // `pre_init_stmts` - Vec<TokenStream2>, -) { - let mut const_app = vec![]; +pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> { let mut stmts = vec![]; - // disable interrupts -- `init` must run with interrupts disabled + // Disable interrupts -- `init` must run with interrupts disabled stmts.push(quote!(rtic::export::interrupt::disable();)); - // populate this core `FreeQueue`s - for (name, senders) in &analysis.free_queues { + // Populate the FreeQueue + for fq in &analysis.free_queues { + // Get the task name + let name = fq.0; let task = &app.software_tasks[name]; let cap = task.args.capacity; - for &sender in senders.keys() { - if sender == core { - let fq = util::fq_ident(name, sender); + let fq_ident = util::fq_ident(name); - stmts.push(quote!( - (0..#cap).for_each(|i| #fq.enqueue_unchecked(i)); - )); - } - } - } - - if app.args.cores == 1 { - stmts.push(quote!( - // To set the variable in cortex_m so the peripherals cannot be taken multiple times - let mut core: rtic::export::Peripherals = rtic::export::Peripherals::steal().into(); - )); - } else { stmts.push(quote!( - // NOTE(transmute) to avoid debug_assertion in multi-core mode - // (This code will go away when we drop multi-core mode) - let mut core: rtic::export::Peripherals = core::mem::transmute(()); + (0..#cap).for_each(|i| #fq_ident.enqueue_unchecked(i)); )); } + stmts.push(quote!( + // To set the variable in cortex_m so the peripherals cannot be taken multiple times + let mut core: rtic::export::Peripherals = rtic::export::Peripherals::steal().into(); + )); + let device = extra.device; let nvic_prio_bits = quote!(#device::NVIC_PRIO_BITS); - // unmask interrupts and set their priorities + // Unmask interrupts and set their priorities for (&priority, name) in analysis .interrupts - .get(&core) .iter() - .flat_map(|interrupts| *interrupts) .chain(app.hardware_tasks.values().flat_map(|task| { if !util::is_exception(&task.args.binds) { Some((&task.args.priority, &task.args.binds)) } else { - // we do exceptions in another pass + // We do exceptions in another pass None } })) { - // compile time assert that this priority is supported by the device + // Compile time assert that this priority is supported by the device stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];)); // NOTE this also checks that the interrupt exists in the `Interrupt` enumeration - let interrupt = util::interrupt_ident(core, app.args.cores); + let interrupt = util::interrupt_ident(); stmts.push(quote!( core.NVIC.set_priority( #device::#interrupt::#name, @@ -86,30 +63,7 @@ pub fn codegen( stmts.push(quote!(rtic::export::NVIC::unmask(#device::#interrupt::#name);)); } - // cross-spawn barriers: now that priorities have been set and the interrupts have been unmasked - // we are ready to receive messages from *other* cores - if analysis.spawn_barriers.contains_key(&core) { - let sb = util::spawn_barrier(core); - let shared = if cfg!(feature = "heterogeneous") { - Some(quote!( - #[rtic::export::shared] - )) - } else { - None - }; - - const_app.push(quote!( - #shared - static #sb: rtic::export::Barrier = rtic::export::Barrier::new(); - )); - - // unblock cores that may send us a message - stmts.push(quote!( - #sb.release(); - )); - } - - // set exception priorities + // Set exception priorities for (name, priority) in app.hardware_tasks.values().filter_map(|task| { if util::is_exception(&task.args.binds) { Some((&task.args.binds, task.args.priority)) @@ -117,7 +71,7 @@ pub fn codegen( None } }) { - // compile time assert that this priority is supported by the device + // Compile time assert that this priority is supported by the device stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];)); stmts.push(quote!(core.SCB.set_priority( @@ -126,11 +80,11 @@ pub fn codegen( );)); } - // initialize the SysTick - if let Some(tq) = analysis.timer_queues.get(&core) { + // Initialize the SysTick if there exist a TimerQueue + if let Some(tq) = analysis.timer_queues.first() { let priority = tq.priority; - // compile time assert that this priority is supported by the device + // Compile time assert that this priority is supported by the device stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];)); stmts.push(quote!(core.SCB.set_priority( @@ -145,23 +99,11 @@ pub fn codegen( )); } - // if there's no user `#[idle]` then optimize returning from interrupt handlers - if app.idles.get(&core).is_none() { + // If there's no user `#[idle]` then optimize returning from interrupt handlers + if app.idles.is_empty() { // Set SLEEPONEXIT bit to enter sleep mode when returning from ISR stmts.push(quote!(core.SCB.scr.modify(|r| r | 1 << 1);)); } - // cross-spawn barriers: wait until other cores are ready to receive messages - for (&receiver, senders) in &analysis.spawn_barriers { - // only block here if `init` can send messages to `receiver` - if senders.get(&core) == Some(&true) { - let sb = util::spawn_barrier(receiver); - - stmts.push(quote!( - #sb.wait(); - )); - } - } - - (const_app, stmts) + stmts } |