diff options
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | book/en/src/internals/tasks.md | 8 | ||||
-rw-r--r-- | examples/shared.rs | 12 | ||||
-rw-r--r-- | examples/static.rs | 12 | ||||
-rw-r--r-- | macros/src/codegen/dispatchers.rs | 6 | ||||
-rw-r--r-- | macros/src/codegen/software_tasks.rs | 10 | ||||
-rw-r--r-- | macros/src/codegen/timer_queue.rs | 4 | ||||
-rw-r--r-- | macros/src/codegen/util.rs | 15 | ||||
-rw-r--r-- | src/export.rs | 9 | ||||
-rw-r--r-- | src/linked_list.rs | 57 | ||||
-rw-r--r-- | src/tq.rs | 8 |
11 files changed, 50 insertions, 94 deletions
@@ -44,9 +44,8 @@ cortex-m = "0.7.0" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.5" } rtic-monotonic = "0.1.0-alpha.2" rtic-core = "0.3.1" -heapless = "0.6.1" +heapless = "0.7.1" bare-metal = "1.0.0" -generic-array = "0.14" [dependencies.dwt-systick-monotonic] version = "0.1.0-alpha.3" diff --git a/book/en/src/internals/tasks.md b/book/en/src/internals/tasks.md index a533dc0c..0407176d 100644 --- a/book/en/src/internals/tasks.md +++ b/book/en/src/internals/tasks.md @@ -78,8 +78,8 @@ mod app { } // ready queue of the task dispatcher - // `U4` is a type-level integer that represents the capacity of this queue - static mut RQ1: Queue<Ready<T1>, U4> = Queue::new(); + // `5-1=4` represents the capacity of this queue + static mut RQ1: Queue<Ready<T1>, 5> = Queue::new(); // interrupt handler chosen to dispatch tasks at priority `1` #[no_mangle] @@ -153,7 +153,7 @@ mod app { // used to track how many more `bar` messages can be enqueued // `U2` is the capacity of the `bar` task; a max of two instances can be queued // this queue is filled by the framework before `init` runs - static mut bar_FQ: Queue<(), U2> = Queue::new(); + static mut bar_FQ: Queue<(), 3> = Queue::new(); // Priority ceiling for the consumer endpoint of `bar_FQ` const bar_FQ_CEILING: u8 = 2; @@ -227,7 +227,7 @@ mod app { // the free queue: used to track free slots in the `baz_INPUTS` array // this queue is initialized with values `0` and `1` before `init` is executed - static mut baz_FQ: Queue<u8, U2> = Queue::new(); + static mut baz_FQ: Queue<u8, 3> = Queue::new(); // Priority ceiling for the consumer endpoint of `baz_FQ` const baz_FQ_CEILING: u8 = 2; diff --git a/examples/shared.rs b/examples/shared.rs index c3fa07b9..9585c388 100644 --- a/examples/shared.rs +++ b/examples/shared.rs @@ -10,23 +10,19 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { use cortex_m_semihosting::{debug, hprintln}; - use heapless::{ - consts::*, - i, - spsc::{Consumer, Producer, Queue}, - }; + use heapless::spsc::{Consumer, Producer, Queue}; use lm3s6965::Interrupt; #[shared] struct Shared { - p: Producer<'static, u32, U4>, - c: Consumer<'static, u32, U4>, + p: Producer<'static, u32, 5>, + c: Consumer<'static, u32, 5>, } #[local] struct Local {} - #[init(local = [q: Queue<u32, U4> = Queue(i::Queue::new())])] + #[init(local = [q: Queue<u32, 5> = Queue::new()])] fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { let (p, c) = cx.local.q.split(); diff --git a/examples/static.rs b/examples/static.rs index f51c5f2d..0ea5d2df 100644 --- a/examples/static.rs +++ b/examples/static.rs @@ -11,23 +11,19 @@ use panic_semihosting as _; mod app { use cortex_m_semihosting::{debug, hprintln}; - use heapless::{ - consts::*, - i, - spsc::{Consumer, Producer, Queue}, - }; + use heapless::spsc::{Consumer, Producer, Queue}; use lm3s6965::Interrupt; #[shared] struct Shared { - p: Producer<'static, u32, U4>, - c: Consumer<'static, u32, U4>, + p: Producer<'static, u32, 5>, + c: Consumer<'static, u32, 5>, } #[local] struct Local {} - #[init(local = [q: Queue<u32, U4> = Queue(i::Queue::new())])] + #[init(local = [q: Queue<u32, 5> = Queue::new()])] fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { let (p, c) = cx.local.q.split(); diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index ac550036..c239b0f8 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -42,15 +42,13 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea } )); - let n = util::capacity_typenum(channel.capacity, true); + let n = util::capacity_literal(channel.capacity as usize + 1); let rq = util::rq_ident(level); let rq = util::mark_internal_ident(&rq); let (rq_ty, rq_expr) = { ( quote!(rtic::export::SCRQ<#t, #n>), - quote!(rtic::export::Queue(unsafe { - rtic::export::iQueue::u8_sc() - })), + quote!(rtic::export::Queue::new()), ) }; diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index cfd21e40..0b073359 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -32,8 +32,8 @@ pub fn codegen( let (_, _, _, input_ty) = util::regroup_inputs(inputs); let cap = task.args.capacity; - let cap_lit = util::capacity_literal(cap); - let cap_ty = util::capacity_typenum(cap, true); + let cap_lit = util::capacity_literal(cap as usize); + let cap_lit_p1 = util::capacity_literal(cap as usize + 1); // Create free queues and inputs / instants buffers let fq = util::fq_ident(name); @@ -41,10 +41,8 @@ pub fn codegen( 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() - })), + quote!(rtic::export::SCFQ<#cap_lit_p1>), + quote!(rtic::export::Queue::new()), Box::new(|| util::link_section_uninit()), ) }; diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 9e30d100..abddbadc 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -62,12 +62,12 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea { // For future use // let doc = &format!("Timer queue for {}", monotonic_name); - let cap = app + let cap: u8 = app .software_tasks .iter() .map(|(_name, task)| task.args.capacity) .sum(); - let n = util::capacity_typenum(cap, false); + let n = util::capacity_literal(cap as usize); let tq_ty = quote!(core::mem::MaybeUninit<rtic::export::TimerQueue<#mono_type, #t, #n>>); diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 86bd6955..c2330d46 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -8,23 +8,10 @@ use syn::{Attribute, Ident, LitInt, PatType}; use crate::check::Extra; /// Turns `capacity` into an unsuffixed integer literal -pub fn capacity_literal(capacity: u8) -> LitInt { +pub fn capacity_literal(capacity: usize) -> LitInt { LitInt::new(&capacity.to_string(), Span::call_site()) } -/// Turns `capacity` into a type-level (`typenum`) integer -pub fn capacity_typenum(capacity: u8, round_up_to_power_of_two: bool) -> TokenStream2 { - let capacity = if round_up_to_power_of_two { - capacity.checked_next_power_of_two().expect("UNREACHABLE") - } else { - capacity - }; - - let ident = Ident::new(&format!("U{}", capacity), Span::call_site()); - - quote!(rtic::export::consts::#ident) -} - /// Identifier for the free queue pub fn fq_ident(task: &Ident) -> Ident { Ident::new(&format!("{}_FQ", task.to_string()), Span::call_site()) diff --git a/src/export.rs b/src/export.rs index 91a4a5ef..e449ef41 100644 --- a/src/export.rs +++ b/src/export.rs @@ -13,13 +13,12 @@ pub use cortex_m::{ peripheral::{scb::SystemHandler, syst::SystClkSource, DWT, NVIC}, Peripherals, }; -use heapless::spsc::SingleCore; -pub use heapless::{consts, i::Queue as iQueue, spsc::Queue}; -pub use heapless::{i::BinaryHeap as iBinaryHeap, BinaryHeap}; +pub use heapless::spsc::Queue; +pub use heapless::BinaryHeap; pub use rtic_monotonic as monotonic; -pub type SCFQ<N> = Queue<u8, N, u8, SingleCore>; -pub type SCRQ<T, N> = Queue<(T, u8), N, u8, SingleCore>; +pub type SCFQ<const N: usize> = Queue<u8, N>; +pub type SCRQ<T, const N: usize> = Queue<(T, u8), N>; #[cfg(armv7m)] #[inline(always)] diff --git a/src/linked_list.rs b/src/linked_list.rs index 9ea4d19f..bbb935f8 100644 --- a/src/linked_list.rs +++ b/src/linked_list.rs @@ -3,8 +3,6 @@ use core::marker::PhantomData; use core::mem::MaybeUninit; use core::ops::{Deref, DerefMut}; use core::ptr; -pub use generic_array::ArrayLength; -use generic_array::GenericArray; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] struct LinkedIndex(u16); @@ -37,21 +35,19 @@ pub struct Node<T> { } /// Iterator for the linked list. -pub struct Iter<'a, T, Kind, N> +pub struct Iter<'a, T, Kind, const N: usize> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { list: &'a LinkedList<T, Kind, N>, index: LinkedIndex, } -impl<'a, T, Kind, N> Iterator for Iter<'a, T, Kind, N> +impl<'a, T, Kind, const N: usize> Iterator for Iter<'a, T, Kind, N> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { type Item = &'a T; @@ -66,11 +62,10 @@ where } /// Comes from [`LinkedList::find_mut`]. -pub struct FindMut<'a, T, Kind, N> +pub struct FindMut<'a, T, Kind, const N: usize> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { list: &'a mut LinkedList<T, Kind, N>, is_head: bool, @@ -79,11 +74,10 @@ where maybe_changed: bool, } -impl<'a, T, Kind, N> FindMut<'a, T, Kind, N> +impl<'a, T, Kind, const N: usize> FindMut<'a, T, Kind, N> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { fn pop_internal(&mut self) -> T { if self.is_head { @@ -122,11 +116,10 @@ where } } -impl<T, Kind, N> Drop for FindMut<'_, T, Kind, N> +impl<T, Kind, const N: usize> Drop for FindMut<'_, T, Kind, N> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { fn drop(&mut self) { // Only resort the list if the element has changed @@ -137,11 +130,10 @@ where } } -impl<T, Kind, N> Deref for FindMut<'_, T, Kind, N> +impl<T, Kind, const N: usize> Deref for FindMut<'_, T, Kind, N> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { type Target = T; @@ -150,11 +142,10 @@ where } } -impl<T, Kind, N> DerefMut for FindMut<'_, T, Kind, N> +impl<T, Kind, const N: usize> DerefMut for FindMut<'_, T, Kind, N> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { fn deref_mut(&mut self) -> &mut Self::Target { self.maybe_changed = true; @@ -162,11 +153,10 @@ where } } -impl<T, Kind, N> fmt::Debug for FindMut<'_, T, Kind, N> +impl<T, Kind, const N: usize> fmt::Debug for FindMut<'_, T, Kind, N> where T: PartialEq + PartialOrd + core::fmt::Debug, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("FindMut") @@ -189,23 +179,21 @@ where } /// The linked list. -pub struct LinkedList<T, Kind, N> +pub struct LinkedList<T, Kind, const N: usize> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { - list: MaybeUninit<GenericArray<Node<T>, N>>, + list: MaybeUninit<[Node<T>; N]>, head: LinkedIndex, free: LinkedIndex, _kind: PhantomData<Kind>, } -impl<T, Kind, N> LinkedList<T, Kind, N> +impl<T, Kind, const N: usize> LinkedList<T, Kind, N> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { /// Internal helper to not do pointer arithmetic all over the place. #[inline] @@ -266,7 +254,7 @@ where _kind: PhantomData, }; - let len = N::U16; + let len = N as u16; let mut free = 0; if len == 0 { @@ -451,11 +439,10 @@ where } } -impl<T, Kind, N> Drop for LinkedList<T, Kind, N> +impl<T, Kind, const N: usize> Drop for LinkedList<T, Kind, N> where T: PartialEq + PartialOrd, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { fn drop(&mut self) { let mut index = self.head; @@ -471,11 +458,10 @@ where } } -impl<T, Kind, N> fmt::Debug for LinkedList<T, Kind, N> +impl<T, Kind, const N: usize> fmt::Debug for LinkedList<T, Kind, N> where T: PartialEq + PartialOrd + core::fmt::Debug, Kind: kind::Kind, - N: ArrayLength<Node<T>>, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish() @@ -518,11 +504,10 @@ pub mod kind { mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; - use generic_array::typenum::consts::*; #[test] fn test_peek() { - let mut ll: LinkedList<u32, Max, U3> = LinkedList::new(); + let mut ll: LinkedList<u32, Max, 3> = LinkedList::new(); ll.push(1).unwrap(); assert_eq!(ll.peek().unwrap(), &1); @@ -533,7 +518,7 @@ mod tests { ll.push(3).unwrap(); assert_eq!(ll.peek().unwrap(), &3); - let mut ll: LinkedList<u32, Min, U3> = LinkedList::new(); + let mut ll: LinkedList<u32, Min, 3> = LinkedList::new(); ll.push(2).unwrap(); assert_eq!(ll.peek().unwrap(), &2); @@ -547,7 +532,7 @@ mod tests { #[test] fn test_full() { - let mut ll: LinkedList<u32, Max, U3> = LinkedList::new(); + let mut ll: LinkedList<u32, Max, 3> = LinkedList::new(); ll.push(1).unwrap(); ll.push(2).unwrap(); ll.push(3).unwrap(); @@ -557,14 +542,14 @@ mod tests { #[test] fn test_empty() { - let ll: LinkedList<u32, Max, U3> = LinkedList::new(); + let ll: LinkedList<u32, Max, 3> = LinkedList::new(); assert!(ll.is_empty()) } #[test] fn test_zero_size() { - let ll: LinkedList<u32, Max, U0> = LinkedList::new(); + let ll: LinkedList<u32, Max, 0> = LinkedList::new(); assert!(ll.is_empty()); assert!(ll.is_full()); @@ -572,7 +557,7 @@ mod tests { #[test] fn test_rejected_push() { - let mut ll: LinkedList<u32, Max, U3> = LinkedList::new(); + let mut ll: LinkedList<u32, Max, 3> = LinkedList::new(); ll.push(1).unwrap(); ll.push(2).unwrap(); ll.push(3).unwrap(); @@ -585,7 +570,7 @@ mod tests { #[test] fn test_updating() { - let mut ll: LinkedList<u32, Max, U3> = LinkedList::new(); + let mut ll: LinkedList<u32, Max, 3> = LinkedList::new(); ll.push(1).unwrap(); ll.push(2).unwrap(); ll.push(3).unwrap(); @@ -1,5 +1,5 @@ use crate::{ - linked_list::{ArrayLength, LinkedList, Min, Node}, + linked_list::{LinkedList, Min}, time::{Clock, Instant}, Monotonic, }; @@ -14,16 +14,14 @@ fn unwrapper<T, E>(val: Result<T, E>) -> T { } } -pub struct TimerQueue<Mono, Task, N>(pub LinkedList<NotReady<Mono, Task>, Min, N>) +pub struct TimerQueue<Mono, Task, const N: usize>(pub LinkedList<NotReady<Mono, Task>, Min, N>) where Mono: Monotonic, - N: ArrayLength<Node<NotReady<Mono, Task>>>, Task: Copy; -impl<Mono, Task, N> TimerQueue<Mono, Task, N> +impl<Mono, Task, const N: usize> TimerQueue<Mono, Task, N> where Mono: Monotonic, - N: ArrayLength<Node<NotReady<Mono, Task>>>, Task: Copy, { pub fn new() -> Self { |