From 7e4779084312cfeca2f7fce5f339127a591e5b2e Mon Sep 17 00:00:00 2001
From: Per Lindgren <per.lindgren@ltu.se>
Date: Sun, 29 Aug 2021 22:21:11 +0200
Subject: [PATCH] wip

---
 Cargo.toml         |  1 +
 examples/rtic-0.rs | 42 ++++++++++++++------------
 src/lib.rs         | 73 +++++++++++++++++++++++++++++++++++++---------
 3 files changed, 83 insertions(+), 33 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 7e7c7d4..c56820f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,7 @@ cortex-m-rt = { version = "0.6.14", features = ["device"] }
 cortex-m-semihosting = "0.3.3"
 panic-halt = "0.2.0"
 # bare-metal = "1.0.0"
+rtic-core = "0.3.1"
 
 # Uncomment for the panic example.
 # panic-itm = "0.4.1"
diff --git a/examples/rtic-0.rs b/examples/rtic-0.rs
index cf14e47..e309c5c 100644
--- a/examples/rtic-0.rs
+++ b/examples/rtic-0.rs
@@ -1,34 +1,34 @@
-//! Overriding an exception handler
-//!
-//! You can override an exception handler using the [`#[exception]`][1] attribute.
-//!
-//! [1]: https://rust-embedded.github.io/cortex-m-rt/0.6.1/cortex_m_rt_macros/fn.exception.html
-//!
-//! ---
+// rtic-0
+// experiment
 
 #![no_main]
 #![no_std]
 
 use panic_halt as _;
 
+use core::cell::Cell;
 use cortex_m::interrupt::free;
 use cortex_m::peripheral::NVIC;
 use cortex_m_rt::entry;
 use cortex_m_semihosting::{debug, hprintln};
 use lm3s6965::{interrupt, Interrupt};
-use rtic_0::{self, init2, App, ConvertNr, Task};
+use rtic_0::{self, ceil, init, task, App, ConvertNr, Resource, Task};
+use rtic_core::Mutex;
+const R1: Resource<u64> = Resource::new(0, 0);
+
+const R2: Resource<u64> = Resource::new(0, ceil![T1, T2]);
 
 const T1: Task = Task {
     interrupt: ConvertNr(Interrupt::UART0.nr()), // UART0
-    prio: 1,
+    prio: 2,
 };
 
 const T2: Task = Task {
     interrupt: ConvertNr(Interrupt::UART1.nr()), // UART1
-    prio: 2,
+    prio: 1,
 };
 
-const TASKS: [Task; 2] = [T1, T2];
+const TASKS: [&'static Task; 2] = [&T1, &T2];
 
 const APP: App = App {
     nvic_priority_bits: lm3s6965::NVIC_PRIO_BITS,
@@ -37,28 +37,32 @@ const APP: App = App {
 
 #[entry]
 fn main() -> ! {
-    init2(&APP);
+    init(&APP);
 
     // test to trigger UART0
     // unsafe { NVIC::unmask(Interrupt::UART0) };
     free(|_cs| {
-        // let t = Interrupt::UART0.nr();
         NVIC::pend(T1.interrupt);
         NVIC::pend(T2.interrupt);
-        // let t = Interrupt::UART1.nr();
-        // NVIC::pend(ConvertNr(Interrupt::UART1.nr()));
     });
     // stop
     debug::exit(debug::EXIT_SUCCESS);
     loop {}
 }
 
-#[interrupt]
-fn UART0() {
-    hprintln!("UART0").ok();
-}
+// #[interrupt]
+// fn UART0() {
+//     hprintln!("UART0").ok();
+//     // uart0(&T1);
+// }
+
+task!(UART0);
+
+fn uart0(prio: u8) {}
 
 #[interrupt]
 fn UART1() {
     hprintln!("UART1").ok();
+    hprintln!("R2 {:?}", R2.ceil).ok();
+    R2.lock(|x| *x + 1);
 }
diff --git a/src/lib.rs b/src/lib.rs
index ba1b69b..60dbe13 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,9 +1,11 @@
 #![no_std]
 
 // use core::ptr::{self, Unique};
-use cortex_m::interrupt::InterruptNumber;
+use core::cell::Cell;
+use cortex_m::interrupt::{InterruptNumber, Nr};
 use cortex_m::peripheral::NVIC;
 use cortex_m_semihosting::hprintln;
+
 pub struct Task {
     pub interrupt: ConvertNr,
     pub prio: u8, // logic priority
@@ -11,7 +13,7 @@ pub struct Task {
 
 pub struct App {
     pub nvic_priority_bits: u8,
-    pub tasks: &'static [Task],
+    pub tasks: &'static [&'static Task],
 }
 
 #[derive(Copy, Clone)]
@@ -23,18 +25,8 @@ unsafe impl InterruptNumber for ConvertNr {
     }
 }
 
-pub fn init(tasks: &[&dyn cortex_m::interrupt::Nr]) {
+pub fn init(app: &App) {
     hprintln!("init").ok();
-    for t in tasks {
-        unsafe {
-            let tmp = ConvertNr(t.nr());
-            NVIC::unmask(tmp);
-        }
-    }
-}
-
-pub fn init2(app: &App) {
-    hprintln!("init2").ok();
     for t in app.tasks {
         unsafe {
             NVIC::unmask(t.interrupt);
@@ -51,4 +43,57 @@ fn logical2hw(priority: u8, prio_bits: u8) -> u8 {
     ((1 << prio_bits) - priority) << (8 - prio_bits)
 }
 
-// core.NVIC.set_priority(Interrupt::UART0, logical2hw(uart0_prio));
+use core::cell::UnsafeCell;
+
+pub struct Resource<T> {
+    data: UnsafeCell<T>,
+    pub ceil: u8,
+}
+
+impl<T> Resource<T> {
+    /// Create a Resource
+    #[inline(always)]
+    pub const fn new(value: T, ceil: u8) -> Self {
+        Resource {
+            data: UnsafeCell::new(value),
+            ceil,
+        }
+    }
+}
+
+#[macro_export]
+macro_rules! ceil {
+    ( $( $x:expr ),* ) => {
+        {
+            let mut temp = 0u8;
+            $(
+                if $x.prio > temp {
+                    temp +=$x.prio;
+                }
+            )*
+            temp
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! task {
+    ($id: ident) => {
+        #[interrupt]
+        fn $id() {
+            hprintln!("UART0").ok();
+            // uart0(&T1);
+        }
+    };
+}
+
+unsafe impl<T> Sync for Resource<T> {}
+
+use rtic_core::Mutex;
+impl<T> Mutex for Resource<T> {
+    type T = T;
+
+    fn lock<R>(&mut self, f: impl FnOnce(&mut T) -> R) -> R {
+        f(&mut self.data.get_mut())
+    }
+}
-- 
GitLab