aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--macros/src/check.rs33
-rw-r--r--macros/src/codegen-verbose.rs226
-rw-r--r--macros/src/codegen.rs10
-rw-r--r--macros/src/codegen/assertions.rs16
-rw-r--r--macros/src/codegen/dispatchers.rs6
-rw-r--r--macros/src/codegen/hardware_tasks.rs6
-rw-r--r--macros/src/codegen/idle.rs4
-rw-r--r--macros/src/codegen/init.rs2
-rw-r--r--macros/src/codegen/locals.rs8
-rw-r--r--macros/src/codegen/module.rs4
-rw-r--r--macros/src/codegen/post_init.rs149
-rw-r--r--macros/src/codegen/pre_init.rs59
-rw-r--r--macros/src/codegen/resources.rs14
-rw-r--r--macros/src/codegen/resources_struct.rs8
-rw-r--r--macros/src/codegen/schedule.rs6
-rw-r--r--macros/src/codegen/software_tasks.rs10
-rw-r--r--macros/src/codegen/spawn.rs9
-rw-r--r--macros/src/codegen/timer_queue.rs10
-rw-r--r--macros/src/codegen/util.rs58
-rw-r--r--macros/src/tests/single.rs2
-rw-r--r--src/cyccnt.rs4
-rw-r--r--src/export.rs4
-rw-r--r--src/lib.rs8
-rw-r--r--src/tq.rs6
24 files changed, 45 insertions, 617 deletions
diff --git a/macros/src/check.rs b/macros/src/check.rs
index f9d1c989..0e57bb73 100644
--- a/macros/src/check.rs
+++ b/macros/src/check.rs
@@ -20,7 +20,7 @@ impl<'a> Extra<'a> {
}
pub fn app<'a>(app: &'a App, analysis: &Analysis) -> parse::Result<Extra<'a>> {
- // check that all exceptions are valid; only exceptions with configurable priorities are
+ // Check that all exceptions are valid; only exceptions with configurable priorities are
// accepted
for (name, task) in &app.hardware_tasks {
let name_s = task.args.binds.to_string();
@@ -48,7 +48,7 @@ pub fn app<'a>(app: &'a App, analysis: &Analysis) -> parse::Result<Extra<'a>> {
}
}
- // check that external (device-specific) interrupts are not named after known (Cortex-M)
+ // Check that external (device-specific) interrupts are not named after known (Cortex-M)
// exceptions
for name in app.extern_interrupts.keys() {
let name_s = name.to_string();
@@ -66,7 +66,7 @@ pub fn app<'a>(app: &'a App, analysis: &Analysis) -> parse::Result<Extra<'a>> {
}
}
- // check that there are enough external interrupts to dispatch the software tasks and the timer
+ // Check that there are enough external interrupts to dispatch the software tasks and the timer
// queue handler
let mut first = None;
let priorities = app
@@ -91,8 +91,7 @@ pub fn app<'a>(app: &'a App, analysis: &Analysis) -> parse::Result<Extra<'a>> {
};
// If not enough tasks and first still is None, may cause
- // "custom attribute panicked"
- // unwrap on None
+ // "custom attribute panicked" due to unwrap on None
return Err(parse::Error::new(first.unwrap().span(), &s));
}
@@ -128,34 +127,10 @@ pub fn app<'a>(app: &'a App, analysis: &Analysis) -> parse::Result<Extra<'a>> {
"peripherals" => match v {
CustomArg::Bool(x) => peripherals = if *x { true } else { false },
-
- /*
- CustomArg::UInt(s) if app.args.cores != 1 => {
- let x = s.parse::<u8>().ok();
- peripherals = if x.is_some() && x.unwrap() < app.args.cores {
- Some(x.unwrap())
- } else {
- return Err(parse::Error::new(
- k.span(),
- &format!(
- "unexpected argument value; \
- this should be an integer in the range 0..={}",
- app.args.cores
- ),
- ));
- }
- }
- */
_ => {
return Err(parse::Error::new(
k.span(),
- //if app.args.cores == 1 {
"unexpected argument value; this should be a boolean",
- /*
- } else {
- "unexpected argument value; this should be an integer"
- },
- */
));
}
},
diff --git a/macros/src/codegen-verbose.rs b/macros/src/codegen-verbose.rs
deleted file mode 100644
index 2b71cf5c..00000000
--- a/macros/src/codegen-verbose.rs
+++ /dev/null
@@ -1,226 +0,0 @@
-use proc_macro2::TokenStream as TokenStream2;
-use quote::quote;
-use rtic_syntax::ast::App;
-
-use crate::{analyze::Analysis, check::Extra};
-
-mod assertions;
-mod dispatchers;
-mod hardware_tasks;
-mod idle;
-mod init;
-mod locals;
-mod module;
-mod post_init;
-mod pre_init;
-mod resources;
-mod resources_struct;
-mod schedule;
-mod schedule_body;
-mod software_tasks;
-mod spawn;
-mod spawn_body;
-mod timer_queue;
-mod util;
-
-// TODO document the syntax here or in `rtic-syntax`
-pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
- let mut const_app = vec![];
- let mut mains = vec![];
- let mut root = vec![];
- let mut user = vec![];
- let mut imports = vec![];
-
- // generate a `main` function for each core
- for core in 0..app.args.cores {
- let assertion_stmts = assertions::codegen(core, analysis, extra);
-
- let (const_app_pre_init, pre_init_stmts) = pre_init::codegen(core, &app, analysis, extra);
-
- let (const_app_init, _root_init, user_init, user_init_imports, call_init) =
- init::codegen(core, app, analysis, extra);
-
- let (const_app_post_init, post_init_stmts) =
- post_init::codegen(core, &app, analysis, extra);
-
- let (const_app_idle, _root_idle, user_idle, user_idle_imports, call_idle) =
- idle::codegen(core, app, analysis, extra);
-
- user.push(quote!(
- /// USER INIT
- #user_init
-
- /// USER IDLE
- #user_idle
- ));
-
- // Stow away the imports generated for each core
- imports.push(quote!(
- /// USER IMPORTS
- #(#user_init_imports)*
-
- /// USER IDLE
- #(#user_idle_imports)*
- ));
-
- root.push(quote!(
- #(#_root_init)*
-
- #(#_root_idle)*
- ));
-
- const_app.push(quote!(
- #(#const_app_pre_init)*
-
- #const_app_init
-
- #(#const_app_post_init)*
-
- #const_app_idle
- ));
-
- let cfg_core = util::cfg_core(core, app.args.cores);
- let main = util::suffixed("main", core);
- let section = util::link_section("text", core);
- mains.push(quote!(
- #[no_mangle]
- #section
- #cfg_core
- unsafe extern "C" fn #main() -> ! {
- #(#assertion_stmts)*
-
- #(#pre_init_stmts)*
-
- #call_init
-
- #(#post_init_stmts)*
-
- #call_idle
- }
- ));
- }
-
- let (const_app_resources, mod_resources, mod_resources_imports) =
- resources::codegen(app, analysis, extra);
-
- let (
- const_app_hardware_tasks,
- root_hardware_tasks,
- user_hardware_tasks,
- user_hardware_tasks_imports,
- ) = hardware_tasks::codegen(app, analysis, extra);
-
- let (
- const_app_software_tasks,
- root_software_tasks,
- user_software_tasks,
- user_software_tasks_imports,
- ) = software_tasks::codegen(app, analysis, extra);
-
- let const_app_dispatchers = dispatchers::codegen(app, analysis, extra);
-
- let const_app_spawn = spawn::codegen(app, analysis, extra);
-
- let const_app_timer_queue = timer_queue::codegen(app, analysis, extra);
-
- let const_app_schedule = schedule::codegen(app, extra);
-
- let cores = app.args.cores.to_string();
- let cfg_core = quote!(#[cfg(core = #cores)]);
- let msg = format!(
- "specified {} core{} but tried to compile for more than {0} core{1}",
- app.args.cores,
- if app.args.cores > 1 { "s" } else { "" }
- );
- let check_excess_cores = quote!(
- #cfg_core
- compile_error!(#msg);
- );
-
- /*
- for s in root.clone() {
- println!("{}", s.to_string());
- }
- */
-
- let user_imports = app.user_imports.clone();
- let user_code = app.user_code.clone();
- let name = &app.name;
- let device = extra.device;
- let endresult = quote!(
- /// USER
- #(#user)*
-
- /// USER_HW_TASKS
- #(#user_hardware_tasks)*
-
- /// USER_SW_TASKS
- #(#user_software_tasks)*
-
- /// ROOT
- //#(#root)*
-
- /// MOD_RESOURCES
- #mod_resources
-
- /// root_hardware_tasks
- #(#root_hardware_tasks)*
-
- /// root_software_tasks
- #(#root_software_tasks)*
-
- /// Implementation details
- mod #name {
- /// Always include the device crate which contains the vector table
- use #device as _;
- #(#imports)*
- /// User imports
- #(#user_imports)*
-
- /// User code from within the module
- #(#user_code)*
-
- /// User hardware tasks import
- #(#user_hardware_tasks_imports)*
-
- /// User software_tasks
- #(#user_software_tasks_imports)*
-
- /// Mod resources imports
- #(#mod_resources_imports)*
-
- #check_excess_cores
-
- /// Const app
- #(#const_app)*
-
- /// Const app resources
- #(#const_app_resources)*
-
- /// Const app hw tasks
- #(#const_app_hardware_tasks)*
-
- /// Const app sw tasks
- #(#const_app_software_tasks)*
-
- /// Const app dispatchers
- #(#const_app_dispatchers)*
-
- /// Const app spawn
- #(#const_app_spawn)*
- /// Const app spawn end
-
- #(#const_app_timer_queue)*
-
- #(#const_app_schedule)*
-
- /// Mains
- #(#mains)*
- }
- );
- for s in endresult.clone() {
- eprintln!("{}", s.to_string());
- }
-
- endresult
-}
diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs
index 35a44bea..fe4d59a6 100644
--- a/macros/src/codegen.rs
+++ b/macros/src/codegen.rs
@@ -30,14 +30,14 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
let mut root = vec![];
let mut user = vec![];
- // generate the `main` function
+ // Generate the `main` function
let assertion_stmts = assertions::codegen(analysis);
let pre_init_stmts = pre_init::codegen(&app, analysis, extra);
let (const_app_init, root_init, user_init, call_init) = init::codegen(app, analysis, extra);
- let (const_app_post_init, post_init_stmts) = post_init::codegen(&app, analysis);
+ let post_init_stmts = post_init::codegen(&app, analysis);
let (const_app_idle, root_idle, user_idle, call_idle) = idle::codegen(app, analysis, extra);
@@ -56,16 +56,12 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
const_app.push(quote!(
#const_app_init
- #(#const_app_post_init)*
-
#const_app_idle
));
let main = util::suffixed("main");
- let section = util::link_section("text");
mains.push(quote!(
#[no_mangle]
- #section
unsafe extern "C" fn #main() -> ! {
let _TODO: () = ();
@@ -115,7 +111,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
#(#root_software_tasks)*
/// Implementation details
- // the user can't access the items within this `const` item
+ // The user can't access the items within this `const` item
const #name: () = {
/// Always include the device crate which contains the vector table
use #device as _;
diff --git a/macros/src/codegen/assertions.rs b/macros/src/codegen/assertions.rs
index ab1b26cd..4d9aae47 100644
--- a/macros/src/codegen/assertions.rs
+++ b/macros/src/codegen/assertions.rs
@@ -7,29 +7,13 @@ use crate::analyze::Analysis;
pub fn codegen(analysis: &Analysis) -> Vec<TokenStream2> {
let mut stmts = vec![];
- // we don't generate *all* assertions on all cores because the user could conditionally import a
- // type only on some core (e.g. `#[cfg(core = "0")] use some::Type;`)
-
- //if let Some(types) = analysis.send_types {
for ty in &analysis.send_types {
stmts.push(quote!(rtic::export::assert_send::<#ty>();));
}
- //}
- //if let Some(types) = analysis.sync_types {
for ty in &analysis.sync_types {
stmts.push(quote!(rtic::export::assert_sync::<#ty>();));
}
- //}
-
- // if the `schedule` API is used in more than one core then we need to check that the
- // `monotonic` timer can be used in multi-core context
- /*
- if analysis.timer_queues.len() > 1 && analysis.timer_queues.contains_key(&core) {
- let monotonic = extra.monotonic();
- stmts.push(quote!(rtic::export::assert_multicore::<#monotonic>();));
- }
- */
stmts
}
diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs
index fdeb6155..300aa996 100644
--- a/macros/src/codegen/dispatchers.rs
+++ b/macros/src/codegen/dispatchers.rs
@@ -42,13 +42,12 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let n = util::capacity_typenum(channel.capacity, true);
let rq = util::rq_ident(level);
- let (rq_ty, rq_expr, section) = {
+ let (rq_ty, rq_expr) = {
(
quote!(rtic::export::SCRQ<#t, #n>),
quote!(rtic::export::Queue(unsafe {
rtic::export::iQueue::u8_sc()
})),
- util::link_section("bss"),
)
};
@@ -58,7 +57,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
);
items.push(quote!(
#[doc = #doc]
- #section
static mut #rq: #rq_ty = #rq_expr;
));
@@ -137,13 +135,11 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
));
let doc = format!("Interrupt handler to dispatch tasks at priority {}", level);
- let section = util::link_section("text");
let interrupt = util::suffixed(&interrupts[&level].to_string());
items.push(quote!(
#[allow(non_snake_case)]
#[doc = #doc]
#[no_mangle]
- #section
unsafe fn #interrupt() {
/// The priority of this interrupt handler
const PRIORITY: u8 = #level;
diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs
index eb86c8d8..7f14b5e1 100644
--- a/macros/src/codegen/hardware_tasks.rs
+++ b/macros/src/codegen/hardware_tasks.rs
@@ -5,7 +5,7 @@ use rtic_syntax::{ast::App, Context};
use crate::{
analyze::Analysis,
check::Extra,
- codegen::{locals, module, resources_struct, util},
+ codegen::{locals, module, resources_struct},
};
/// Generate support code for hardware tasks (`#[exception]`s and `#[interrupt]`s)
@@ -49,11 +49,9 @@ pub fn codegen(
let symbol = task.args.binds.clone();
let priority = task.args.priority;
- let section = util::link_section("text");
const_app.push(quote!(
#[allow(non_snake_case)]
#[no_mangle]
- #section
unsafe fn #symbol() {
const PRIORITY: u8 = #priority;
@@ -104,12 +102,10 @@ pub fn codegen(
let attrs = &task.attrs;
let context = &task.context;
let stmts = &task.stmts;
- let section = util::link_section("text");
let locals_pat = locals_pat.iter();
user_tasks.push(quote!(
#(#attrs)*
#[allow(non_snake_case)]
- #section
fn #name(#(#locals_pat,)* #context: #name::Context) {
use rtic::Mutex as _;
diff --git a/macros/src/codegen/idle.rs b/macros/src/codegen/idle.rs
index cd97764e..d0bff3e7 100644
--- a/macros/src/codegen/idle.rs
+++ b/macros/src/codegen/idle.rs
@@ -5,7 +5,7 @@ use rtic_syntax::{ast::App, Context};
use crate::{
analyze::Analysis,
check::Extra,
- codegen::{locals, module, resources_struct, util},
+ codegen::{locals, module, resources_struct},
};
/// Generates support code for `#[idle]` functions
@@ -56,12 +56,10 @@ pub fn codegen(
let attrs = &idle.attrs;
let context = &idle.context;
let stmts = &idle.stmts;
- let section = util::link_section("text");
let locals_pat = locals_pat.iter();
let user_idle = Some(quote!(
#(#attrs)*
#[allow(non_snake_case)]
- #section
fn #name(#(#locals_pat,)* #context: #name::Context) -> ! {
use rtic::Mutex as _;
diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs
index 94f57afb..e0b7d699 100644
--- a/macros/src/codegen/init.rs
+++ b/macros/src/codegen/init.rs
@@ -81,12 +81,10 @@ pub fn codegen(
let context = &init.context;
let attrs = &init.attrs;
let stmts = &init.stmts;
- let section = util::link_section("text");
let locals_pat = locals_pat.iter();
let user_init = Some(quote!(
#(#attrs)*
#[allow(non_snake_case)]
- #section
fn #name(#(#locals_pat,)* #context: #name::Context) #ret {
#(#stmts)*
}
diff --git a/macros/src/codegen/locals.rs b/macros/src/codegen/locals.rs
index b3c593a2..336c0b21 100644
--- a/macros/src/codegen/locals.rs
+++ b/macros/src/codegen/locals.rs
@@ -41,13 +41,6 @@ pub fn codegen(
let cfgs = &local.cfgs;
has_cfgs |= !cfgs.is_empty();
- /*
- let section = if local.shared && cfg!(feature = "heterogeneous") {
- Some(quote!(#[rtic::export::shared]))
- } else {
- util::link_section("data", core)
- };
- */
let expr = &local.expr;
let ty = &local.ty;
fields.push(quote!(
@@ -56,7 +49,6 @@ pub fn codegen(
));
items.push(quote!(
#(#cfgs)*
- //#section
static mut #name: #ty = #expr
));
values.push(quote!(
diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs
index 4b3d0cf7..863f6c5b 100644
--- a/macros/src/codegen/module.rs
+++ b/macros/src/codegen/module.rs
@@ -11,7 +11,6 @@ pub fn codegen(ctxt: Context, resources_tick: bool, app: &App, extra: &Extra) ->
let name = ctxt.ident(app);
- //let core = ctxt.core(app);
let mut needs_instant = false;
let mut lt = None;
match ctxt {
@@ -312,12 +311,9 @@ pub fn codegen(ctxt: Context, resources_tick: bool, app: &App, extra: &Extra) ->
));
if !items.is_empty() {
- //let cfg_core = util::cfg_core(ctxt.core(app), app.args.cores);
-
quote!(
#[allow(non_snake_case)]
#[doc = #doc]
- //#cfg_core
pub mod #name {
#(#items)*
}
diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs
index 93d57049..c35c6976 100644
--- a/macros/src/codegen/post_init.rs
+++ b/macros/src/codegen/post_init.rs
@@ -5,19 +5,14 @@ use rtic_syntax::ast::App;
use crate::analyze::Analysis;
/// Generates code that runs after `#[init]` returns
-pub fn codegen(app: &App, analysis: &Analysis) -> (Vec<TokenStream2>, Vec<TokenStream2>) {
- //#TODO remove
- let const_app = vec![];
+pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
let mut stmts = vec![];
- // initialize late resources
- //if let Some(late_resources) = analysis.late_resources {
- //for name in late_resources {
+ // Initialize late resources
if analysis.late_resources.len() > 0 {
- // #TODO, check soundness of this, why the wrapping
// BTreeSet wrapped in a vector
- for name in &analysis.late_resources[0] {
- // if it's live
+ for name in analysis.late_resources.first().unwrap() {
+ // If it's live
let cfgs = app.late_resources[name].cfgs.clone();
if analysis.locations.get(name).is_some() {
// Need to also include the cfgs
@@ -29,140 +24,8 @@ pub fn codegen(app: &App, analysis: &Analysis) -> (Vec<TokenStream2>, Vec<TokenS
}
}
- /*
- if analysis.timer_queues.is_empty() {
- /*
- // cross-initialization barriers -- notify *other* cores that their resources have been
- // initialized
- for (user, initializers) in &analysis.initialization_barriers {
- if !initializers.contains(&core) {
- continue;
- }
-
- let ib = util::init_barrier(*user);
- let shared = if cfg!(feature = "heterogeneous") {
- Some(quote!(
- #[rtic::export::shared]
- ))
- } else {
- None
- };
-
- const_app.push(quote!(
- #shared
- static #ib: rtic::export::Barrier = rtic::export::Barrier::new();
- ));
-
- stmts.push(quote!(
- #ib.release();
- ));
- }
- */
-
- /*
- // then wait until the other cores have initialized *our* resources
- if analysis.initialization_barriers.contains_key(&core) {
- let ib = util::init_barrier(core);
-
- stmts.push(quote!(
- #ib.wait();
- ));
- }
-
- // cross-spawn barriers: wait until other cores are ready to receive messages
- for (&receiver, senders) in &analysis.spawn_barriers {
- if senders.get(&core) == Some(&false) {
- let sb = util::spawn_barrier(receiver);
-
- stmts.push(quote!(
- #sb.wait();
- ));
- }
- }
- */
- } else {
- // if the `schedule` API is used then we'll synchronize all cores to leave the
- // `init`-ialization phase at the same time. In this case the rendezvous barrier makes the
- // cross-initialization and spawn barriers unnecessary
-
- let m = extra.monotonic();
-
- if analysis.timer_queues.len() == 1 {
- // reset the monotonic timer / counter
- stmts.push(quote!(
- <#m as rtic::Monotonic>::reset();
- ));
- } else {
- // in the multi-core case we need a rendezvous (RV) barrier between *all* the cores that
- // use the `schedule` API; otherwise one of the cores could observe the before-reset
- // value of the monotonic counter
- // (this may be easier to implement with `AtomicU8.fetch_sub` but that API is not
- // available on ARMv6-M)
-
- // this core will reset the monotonic counter
- const FIRST: u8 = 0;
-
- if core == FIRST {
- for &i in analysis.timer_queues.keys() {
- let rv = util::rendezvous_ident(i);
- let shared = if cfg!(feature = "heterogeneous") {
- Some(quote!(
- #[rtic::export::shared]
- ))
- } else {
- None
- };
-
- const_app.push(quote!(
- #shared
- static #rv: rtic::export::Barrier = rtic::export::Barrier::new();
- ));
-
- // wait until all the other cores have reached the RV point
- if i != FIRST {
- stmts.push(quote!(
- #rv.wait();
- ));
- }
- }
-
- let rv = util::rendezvous_ident(core);
- stmts.push(quote!(
- // the compiler fences are used to prevent `reset` from being re-ordering wrt to
- // the atomic operations -- we don't know if `reset` contains load or store
- // operations
-
- core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
-
- // reset the counter
- <#m as rtic::Monotonic>::reset();
-
- core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
-
- // now unblock all the other cores
- #rv.release();
- ));
- } else {
- let rv = util::rendezvous_ident(core);
-
- // let the first core know that we have reached the RV point
- stmts.push(quote!(
- #rv.release();
- ));
-
- let rv = util::rendezvous_ident(FIRST);
-
- // wait until the first core has reset the monotonic timer
- stmts.push(quote!(
- #rv.wait();
- ));
- }
- }
- }
- */
-
- // enable the interrupts -- this completes the `init`-ialization phase
+ // Enable the interrupts -- this completes the `init`-ialization phase
stmts.push(quote!(rtic::export::interrupt::enable();));
- (const_app, stmts)
+ stmts
}
diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs
index 80849aea..9c5f35ec 100644
--- a/macros/src/codegen/pre_init.rs
+++ b/macros/src/codegen/pre_init.rs
@@ -8,10 +8,10 @@ use crate::{analyze::Analysis, check::Extra, codegen::util};
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 the FreeQueue
+ // Populate the FreeQueue
for fq in &analysis.free_queues {
// Get the task name
let name = fq.0;
@@ -33,7 +33,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
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
.iter()
@@ -41,12 +41,12 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
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
@@ -63,32 +63,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
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))
@@ -96,7 +71,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
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(
@@ -105,11 +80,11 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
);));
}
- // initialize the SysTick if there exist a TimerQueue
+ // 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(
@@ -124,25 +99,11 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
));
}
- // if there's no user `#[idle]` then optimize returning from interrupt handlers
+ // 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();
- ));
- }
- }
- */
-
stmts
}
diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs
index 51467618..4196ee7a 100644
--- a/macros/src/codegen/resources.rs
+++ b/macros/src/codegen/resources.rs
@@ -23,24 +23,11 @@ pub fn codegen(
let ty = &res.ty;
{
- //let loc_attr = None;
let section = if expr.is_none() {
util::link_section_uninit(true)
} else {
None
};
- /*
- let (loc_attr, section) = match loc {
- Location::Owned => (
- None,
- if expr.is_none() {
- util::link_section_uninit(true)
- } else {
- None
- },
- ),
- };
- */
let (ty, expr) = if let Some(expr) = expr {
(quote!(#ty), quote!(#expr))
@@ -56,7 +43,6 @@ pub fn codegen(
#[allow(non_upper_case_globals)]
#(#attrs)*
#(#cfgs)*
- //#loc_attr
#section
static mut #name: #ty = #expr;
));
diff --git a/macros/src/codegen/resources_struct.rs b/macros/src/codegen/resources_struct.rs
index 0c5efd3a..dbbba30e 100644
--- a/macros/src/codegen/resources_struct.rs
+++ b/macros/src/codegen/resources_struct.rs
@@ -39,7 +39,7 @@ pub fn codegen(
if ctxt.is_init() {
if !analysis.ownerships.contains_key(name) {
- // owned by `init`
+ // Owned by `init`
fields.push(quote!(
#(#cfgs)*
pub #name: &'static #mut_ #ty
@@ -50,7 +50,7 @@ pub fn codegen(
#name: &#mut_ #name
));
} else {
- // owned by someone else
+ // Owned by someone else
lt = Some(quote!('a));
fields.push(quote!(
@@ -75,7 +75,7 @@ pub fn codegen(
pub #name: &'a #ty
));
} else {
- // resource proxy
+ // Resource proxy
lt = Some(quote!('a));
fields.push(quote!(
@@ -136,7 +136,7 @@ pub fn codegen(
if lt.is_some() {
*needs_lt = true;
- // the struct could end up empty due to `cfg`s leading to an error due to `'a` being unused
+ // The struct could end up empty due to `cfg`s leading to an error due to `'a` being unused
if has_cfgs {
fields.push(quote!(
#[doc(hidden)]
diff --git a/macros/src/codegen/schedule.rs b/macros/src/codegen/schedule.rs
index b6cb6b9a..46b0f384 100644
--- a/macros/src/codegen/schedule.rs
+++ b/macros/src/codegen/schedule.rs
@@ -32,10 +32,8 @@ pub fn codegen(app: &App, extra: &Extra) -> Vec<TokenStream2> {
let body = schedule_body::codegen(scheduler, &name, app);
- let section = util::link_section("text");
methods.push(quote!(
#(#cfgs)*
- #section
fn #name(&self, instant: #instant #(,#args)*) -> Result<(), #ty> {
#body
}
@@ -44,15 +42,13 @@ pub fn codegen(app: &App, extra: &Extra) -> Vec<TokenStream2> {
let schedule = util::schedule_ident(name);
if !seen.contains(name) {
- // generate a `schedule_${name}_S${sender}` function
+ // Generate a `schedule_${name}_S${sender}` function
seen.insert(name);
let body = schedule_body::codegen(scheduler, &name, app);
- let section = util::link_section("text");
items.push(quote!(
#(#cfgs)*
- #section
unsafe fn #schedule(
priority: &rtic::export::Priority,
instant: #instant
diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs
index 25662801..b56db419 100644
--- a/macros/src/codegen/software_tasks.rs
+++ b/macros/src/codegen/software_tasks.rs
@@ -35,26 +35,22 @@ pub fn codegen(
let cap_lit = util::capacity_literal(cap);
let cap_ty = util::capacity_typenum(cap, true);
- // create free queues and inputs / instants buffers
- //if let Some(free_queues) = analysis.free_queues.get(name) {
- //for (&sender, &ceiling) in free_queues {
+ // Create free queues and inputs / instants buffers
if let Some(&ceiling) = analysis.free_queues.get(name) {
let fq = util::fq_ident(name);
- let (fq_ty, fq_expr, bss, mk_uninit): (_, _, _, Box<dyn Fn() -> Option<_>>) = {
+ let (fq_ty, fq_expr, mk_uninit): (_, _, Box<dyn Fn() -> Option<_>>) = {
(
quote!(rtic::export::SCFQ<#cap_ty>),
quote!(rtic::export::Queue(unsafe {
rtic::export::iQueue::u8_sc()
})),
- util::link_section("bss"),
Box::new(|| util::link_section_uninit(true)),
)
};
const_app.push(quote!(
/// Queue version of a free-list that keeps track of empty slots in
/// the following buffers
- #bss
static mut #fq: #fq_ty = #fq_expr;
));
@@ -130,7 +126,6 @@ pub fn codegen(
root.push(struct_);
}
- let section = util::link_section("text");
let context = &task.context;
let attrs = &task.attrs;
let cfgs = &task.cfgs;
@@ -140,7 +135,6 @@ pub fn codegen(
#(#attrs)*
#(#cfgs)*
#[allow(non_snake_case)]
- #section
fn #name(#(#locals_pat,)* #context: #name::Context #(,#inputs)*) {
use rtic::Mutex as _;
diff --git a/macros/src/codegen/spawn.rs b/macros/src/codegen/spawn.rs
index 6cad809b..4b824f56 100644
--- a/macros/src/codegen/spawn.rs
+++ b/macros/src/codegen/spawn.rs
@@ -20,7 +20,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
for name in spawnees {
let spawnee = &app.software_tasks[name];
- //let receiver = spawnee.args.core;
let cfgs = &spawnee.cfgs;
let (args, _, untupled, ty) = util::regroup_inputs(&spawnee.inputs);
let args = &args;
@@ -39,10 +38,8 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
None
};
- let section = util::link_section("text");
methods.push(quote!(
#(#cfgs)*
- #section
fn #name(&self #(,#args)*) -> Result<(), #ty> {
#let_instant
#body
@@ -52,7 +49,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let spawn = util::spawn_ident(name);
if !seen.contains(name) {
- // generate a `spawn_${name}_S${sender}` function
+ // Generate a `spawn_${name}_S${sender}` function
seen.insert(name);
let instant = if app.uses_schedule() {
@@ -65,11 +62,8 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let body = spawn_body::codegen(spawner, &name, app, analysis, extra);
- let section = util::link_section("text");
items.push(quote!(
- //#cfg_sender
#(#cfgs)*
- #section
unsafe fn #spawn(
priority: &rtic::export::Priority
#instant
@@ -117,7 +111,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let spawner = spawner.ident(app);
debug_assert!(!methods.is_empty());
items.push(quote!(
- //#cfg_sender
impl<#lt> #spawner::Spawn<#lt> {
#(#methods)*
}
diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs
index 41f5520e..030158e2 100644
--- a/macros/src/codegen/timer_queue.rs
+++ b/macros/src/codegen/timer_queue.rs
@@ -9,7 +9,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let mut items = vec![];
if let Some(timer_queue) = &analysis.timer_queues.first() {
- //let cfg_sender = util::cfg_core(sender, app.args.cores);
let t = util::schedule_t_ident();
// Enumeration of `schedule`-able tasks
@@ -29,7 +28,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let doc = format!("Tasks that can be scheduled");
items.push(quote!(
- //#cfg_sender
#[doc = #doc]
#[allow(non_camel_case_types)]
#[derive(Clone, Copy)]
@@ -48,18 +46,14 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let n = util::capacity_typenum(timer_queue.capacity, false);
let tq_ty = quote!(rtic::export::TimerQueue<#m, #t, #n>);
- let section = util::link_section("bss");
items.push(quote!(
- //#cfg_sender
#[doc = #doc]
- #section
static mut #tq: #tq_ty = rtic::export::TimerQueue(
rtic::export::BinaryHeap(
rtic::export::iBinaryHeap::new()
)
);
- //#cfg_sender
struct #tq<'a> {
priority: &'a rtic::export::Priority,
}
@@ -68,7 +62,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
items.push(util::impl_mutex(
extra,
&[],
- //cfg_sender.as_ref(),
false,
&tq,
tq_ty,
@@ -114,11 +107,8 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let priority = timer_queue.priority;
let sys_tick = util::suffixed("SysTick");
- let section = util::link_section("text");
items.push(quote!(
#[no_mangle]
- //#cfg_sender
- #section
unsafe fn #sys_tick() {
use rtic::Mutex as _;
diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs
index f4dbca39..2f9f3cce 100644
--- a/macros/src/codegen/util.rs
+++ b/macros/src/codegen/util.rs
@@ -25,24 +25,7 @@ pub fn capacity_typenum(capacity: u8, round_up_to_power_of_two: bool) -> TokenSt
quote!(rtic::export::consts::#ident)
}
-/*
-/// Generates a `#[cfg(core = "0")]` attribute if we are in multi-core mode
-pub fn cfg_core(core: Core, cores: u8) -> Option<TokenStream2> {
- if cores == 1 {
- None
- } else if cfg!(feature = "heterogeneous") {
- let core = core.to_string();
- Some(quote!(#[cfg(core = #core)]))
- } else {
- None
- }
-}
-*/
-
/// Identifier for the free queue
-///
-/// There may be more than one free queue per task because we need one for each sender core so we
-/// include the sender (e.g. `S0`) in the name
pub fn fq_ident(task: &Ident) -> Ident {
Ident::new(&format!("{}_FQ", task.to_string()), Span::call_site())
}
@@ -51,7 +34,6 @@ pub fn fq_ident(task: &Ident) -> Ident {
pub fn impl_mutex(
extra: &Extra,
cfgs: &[Attribute],
- //cfg_core: Option<&TokenStream2>,
resources_prefix: bool,
name: &Ident,
ty: TokenStream2,
@@ -67,7 +49,6 @@ pub fn impl_mutex(
let device = extra.device;
quote!(
#(#cfgs)*
- //#cfg_core
impl<'a> rtic::Mutex for #path<'a> {
type T = #ty;
@@ -90,13 +71,6 @@ pub fn impl_mutex(
)
}
-/*
-/// Generates an identifier for a cross-initialization barrier
-pub fn init_barrier(initializer: Core) -> Ident {
- Ident::new(&format!("IB{}", initializer), Span::call_site())
-}
-*/
-
/// Generates an identifier for the `INPUTS` buffer (`spawn` & `schedule` API)
pub fn inputs_ident(task: &Ident) -> Ident {
Ident::new(&format!("{}_INPUTS", task), Span::call_site())
@@ -138,18 +112,6 @@ fn link_section_index() -> usize {
INDEX.fetch_add(1, Ordering::Relaxed)
}
-pub fn link_section(_section: &str) -> Option<TokenStream2> {
- /*
- if cfg!(feature = "homogeneous") {
- let section = format!(".{}_{}.rtic{}", section, core, link_section_index());
- Some(quote!(#[link_section = #section]))
- } else {
- None
- }
- */
- None
-}
-
// NOTE `None` means in shared memory
pub fn link_section_uninit(empty_expr: bool) -> Option<TokenStream2> {
let section = if empty_expr {
@@ -175,13 +137,6 @@ pub fn locals_ident(ctxt: Context, app: &App) -> Ident {
Ident::new(&s, Span::call_site())
}
-/*
-/// Generates an identifier for a rendezvous barrier
-pub fn rendezvous_ident() -> Ident {
- Ident::new(&format!("RV"), Span::call_site())
-}
-*/
-
// Regroups the inputs of a task
//
// `inputs` could be &[`input: Foo`] OR &[`mut x: i32`, `ref y: i64`]
@@ -246,17 +201,15 @@ pub fn resources_ident(ctxt: Context, app: &App) -> Ident {
/// Generates an identifier for a ready queue
///
-/// Each core may have several task dispatchers, one for each priority level. Each task dispatcher
-/// in turn may use more than one ready queue because the queues are SPSC queues so one is needed
-/// per sender core.
+/// There may be several task dispatchers, one for each priority level.
+/// The ready queues are SPSC queues
pub fn rq_ident(priority: u8) -> Ident {
Ident::new(&format!("P{}_RQ", priority), Span::call_site())
}
/// Generates an identifier for a "schedule" function
///
-/// The methods of the `Schedule` structs invoke these functions. As one task may be `schedule`-ed
-/// by different cores we need one "schedule" function per possible task-sender pair
+/// The methods of the `Schedule` structs invoke these functions.
pub fn schedule_ident(name: &Ident) -> Ident {
Ident::new(&format!("schedule_{}", name.to_string()), Span::call_site())
}
@@ -268,8 +221,7 @@ pub fn schedule_t_ident() -> Ident {
/// Generates an identifier for a "spawn" function
///
-/// The methods of the `Spawn` structs invoke these functions. As one task may be `spawn`-ed by
-/// different cores we need one "spawn" function per possible task-sender pair
+/// The methods of the `Spawn` structs invoke these functions.
pub fn spawn_ident(name: &Ident) -> Ident {
Ident::new(&format!("spawn_{}", name.to_string()), Span::call_site())
}
@@ -289,7 +241,7 @@ pub fn suffixed(name: &str) -> Ident {
/// Generates an identifier for a timer queue
///
-/// At most there's one timer queue per core
+/// At most there is one timer queue
pub fn tq_ident() -> Ident {
Ident::new(&format!("TQ"), Span::call_site())
}
diff --git a/macros/src/tests/single.rs b/macros/src/tests/single.rs
index 6d4fb23a..d6693882 100644
--- a/macros/src/tests/single.rs
+++ b/macros/src/tests/single.rs
@@ -15,7 +15,7 @@ fn analyze() {
#[task(priority = 2)]
fn b(_: b::Context) {}
- // first interrupt is assigned to the highest priority dispatcher
+ // First interrupt is assigned to the highest priority dispatcher
extern "C" {
fn B();
fn A();
diff --git a/src/cyccnt.rs b/src/cyccnt.rs
index 6bc2ef0a..8e07b001 100644
--- a/src/cyccnt.rs
+++ b/src/cyccnt.rs
@@ -19,10 +19,6 @@ use crate::Fraction;
/// Adding or subtracting a `Duration` of more than `(1 << 31)` cycles to an `Instant` effectively
/// makes it "wrap around" and creates an incorrect value. This is also true if the operation is
/// done in steps, e.g. `(instant + dur) + dur` where `dur` is `(1 << 30)` ticks.
-///
-/// In multi-core contexts: this value is tied to the CYCCNT of *one* core so sending it a different
-/// core makes it lose its meaning -- each Cortex-M core has its own CYCCNT counter and these are
-/// usually unsynchronized and may even be running at different frequencies.
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Instant {
inner: i32,
diff --git a/src/export.rs b/src/export.rs
index 8e5ef433..8a5d4e3e 100644
--- a/src/export.rs
+++ b/src/export.rs
@@ -28,7 +28,7 @@ where
F: FnOnce(),
{
if priority == 1 {
- // if the priority of this interrupt is `1` then BASEPRI can only be `0`
+ // If the priority of this interrupt is `1` then BASEPRI can only be `0`
f();
unsafe { basepri::write(0) }
} else {
@@ -80,7 +80,7 @@ impl Priority {
}
}
- // these two methods are used by `lock` (see below) but can't be used from the RTIC application
+ // These two methods are used by `lock` (see below) but can't be used from the RTIC application
#[inline(always)]
fn set(&self, value: u8) {
self.inner.set(value)
diff --git a/src/lib.rs b/src/lib.rs
index 1c50f78f..a7d399cd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -28,13 +28,6 @@
//! release.
//!
//! [SemVer]: https://semver.org/spec/v2.0.0.html
-//!
-//! # Cargo features
-//!
-//! - `heterogeneous`. This opt-in feature enables the *experimental* heterogeneous multi-core
-//! support. This feature depends on unstable feature and requires the use of the nightly channel.
-//!
-//! - `homogeneous`. This opt-in feature enables the *experimental* homogeneous multi-core support.
#![deny(missing_docs)]
#![deny(rust_2018_compatibility)]
@@ -48,7 +41,6 @@ use cortex_m::{
interrupt::Nr,
peripheral::{CBP, CPUID, DCB, DWT, FPB, FPU, ITM, MPU, NVIC, SCB, TPIU},
};
-#[cfg(all(not(feature = "heterogeneous"), not(feature = "homogeneous")))]
use cortex_m_rt as _; // vector table
pub use cortex_m_rtic_macros::app;
pub use rtic_core::{Exclusive, Mutex};
diff --git a/src/tq.rs b/src/tq.rs
index 21beeb9c..9300dbfc 100644
--- a/src/tq.rs
+++ b/src/tq.rs
@@ -40,7 +40,7 @@ where
mem::transmute::<_, SYST>(()).enable_interrupt();
}
- // set SysTick pending
+ // Set SysTick pending
SCB::set_pendst();
}
@@ -79,13 +79,13 @@ where
};
mem::transmute::<_, SYST>(()).set_reload(dur);
- // start counting down from the new reload
+ // Start counting down from the new reload
mem::transmute::<_, SYST>(()).clear_current();
None
}
} else {
- // the queue is empty
+ // The queue is empty
mem::transmute::<_, SYST>(()).disable_interrupt();
None