1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
/*********************************************************************************************************************** * Copyright (c) 2019 by the authors * * Author: André Borrmann * License: Apache License 2.0 **********************************************************************************************************************/ #![doc(html_root_url = "https://docs.rs/ruspiro-lock/0.2.1")] #![no_std] #![feature(asm)] //! # Atomic locks for Raspberry Pi baremetal systems //! //! This crate provides two options of locks. [Spinlock] and [Semaphore]. They provide mechanisms to secure cross core //! access to shared data like MMIO registers of peripherals. As the locks depend on low level atomics they do only work //! on the Raspberry Pi if the MMU is properly configured. Otherwise using either of the lock functions will hang the //! core it has been used on. //! //! # Usage //! //! Using a Spinlock to ensure exclusive access. //! ``` //! use ruspiro_lock::*; //! //! static SPIN: Spinlock = Spinlock::new(); //! //! fn main() { //! SPIN.aquire(); //! // following code is only executed if the lock could be aquired, the executing core pause till then //! let _ = 10 + 3; //! SPIN.release(); //! } //! ``` //! //! Using a Semaphore to specify how often specific access is valid. //! //! ``` //! use ruspriro_lock::*; //! //! static mut SEMA: Semaphore = Semaphore::new(1); //! //! fn main() { //! unsafe { // unsafe necessary as accessing mut static's is unsafe //! if SEMA.try_down().is_ok() { //! // we gained access to the semaphore, do something //! let _ = 20 /4; //! SEMA.up(); //! } //! } //! } //! ``` //! //! Using data container with atmic lock guard. //! ``` //! use ruspiro_lock::*; //! //! static DATA: DataLock<u32> = DataLock::new(0); //! //! fn main() { //! if let Some(mut data) = DATA.try_lock() { //! *data = 20; //! } //! // once the data goes ot of scope the lock will be released //! if let Some(data) = DATA.try_lock() { //! println!("data: {}", *data); //! //! // another lock should fail inside this scope //! assert_eq!(DATA.try_lock(), None); //! } //! } //! ``` //! // re-export the spinlock pub mod spinlock; pub use spinlock::*; // re-export the semaphore pub mod semaphore; pub use semaphore::*; // re-export the data-lock pub mod datalock; pub use datalock::*; use ruspiro_interrupt_core::*;