Skip to content

Instantly share code, notes, and snippets.

@korken89
Last active September 10, 2019 07:13
Show Gist options
  • Save korken89/ddf4aa8a4e5f66a2b80b42352844a687 to your computer and use it in GitHub Desktop.
Save korken89/ddf4aa8a4e5f66a2b80b42352844a687 to your computer and use it in GitHub Desktop.
Mutex trait test
//! main.rs
#![no_main]
#![no_std]
use core::{
cell::RefCell,
marker::{Send, Sync},
};
use cortex_m::interrupt::CriticalSection;
use cortex_m_rt::entry;
use hal::nrf52832_pac::interrupt;
use nrf52832_hal as hal;
use panic_halt as _;
use mutex_trait::Mutex as _;
static MUT: Mutex<RefCell<i32>> = Mutex::new(RefCell::new(0));
#[entry]
fn init() -> ! {
let mut r = &MUT;
// Locking!!
r.lock(|data| *data += 1);
loop {}
}
#[interrupt]
fn SWI0_EGU0() {
let mut r = &MUT;
// Locking!!
r.lock(|data| *data += 1);
// More Locking!!
increment_in_mutex(&mut r);
}
// Look no RefCell and a lock!!!
fn increment_in_mutex(m: &mut impl mutex_trait::Mutex<Data = i32>) {
m.lock(|data| *data += 1);
}
// -------------------------------- Impl bellow here --------------------------
pub mod mutex_trait {
pub trait Mutex {
/// Data protected by the mutex
type Data;
/// Creates a critical section and grants temporary access to the protected data
fn lock<R>(&mut self, f: impl FnOnce(&mut Self::Data) -> R) -> R;
}
}
struct Mutex<T> {
data: T,
}
impl<T> Mutex<T> {
pub const fn new(data: T) -> Self {
Self { data }
}
fn access(&self, _cs: &CriticalSection) -> &T {
&self.data
}
}
impl<'a, T> mutex_trait::Mutex for &'a Mutex<RefCell<T>> {
type Data = T;
fn lock<R>(&mut self, f: impl FnOnce(&mut Self::Data) -> R) -> R {
cortex_m::interrupt::free(|cs| f(&mut *self.access(cs).borrow_mut()))
}
}
unsafe impl<T> Sync for Mutex<T> where T: Send {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment