freertos_next/
semaphore.rs1use crate::base::*;
2use crate::isr::*;
3use crate::shim::*;
4use crate::units::*;
5
6pub struct Semaphore {
8 semaphore: FreeRtosSemaphoreHandle,
9}
10
11unsafe impl Send for Semaphore {}
12unsafe impl Sync for Semaphore {}
13
14impl Semaphore {
15 pub fn new_binary() -> Result<Semaphore, FreeRtosError> {
17 unsafe {
18 let s = freertos_rs_create_binary_semaphore();
19 if s == 0 as *const _ {
20 return Err(FreeRtosError::OutOfMemory);
21 }
22 Ok(Semaphore { semaphore: s })
23 }
24 }
25
26 #[cfg(feature = "counting-semaphore")]
28 pub fn new_counting(max: u32, initial: u32) -> Result<Semaphore, FreeRtosError> {
29 unsafe {
30 let s = freertos_rs_create_counting_semaphore(max, initial);
31 if s == 0 as *const _ {
32 return Err(FreeRtosError::OutOfMemory);
33 }
34 Ok(Semaphore { semaphore: s })
35 }
36 }
37
38 #[inline]
45 pub unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self {
46 Self { semaphore: handle }
47 }
48 #[inline]
49 pub fn raw_handle(&self) -> FreeRtosSemaphoreHandle {
50 self.semaphore
51 }
52
53 pub fn lock<D: DurationTicks>(&self, max_wait: D) -> Result<SemaphoreGuard<'_>, FreeRtosError> {
55 self.take(max_wait).map(|()| SemaphoreGuard { owner: self })
56 }
57
58 pub fn give(&self) -> bool {
60 unsafe { freertos_rs_give_semaphore(self.semaphore) == 0 }
61 }
62
63 pub fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError> {
64 unsafe {
65 let res = freertos_rs_take_semaphore(self.semaphore, max_wait.to_ticks());
66
67 if res != 0 {
68 return Err(FreeRtosError::Timeout);
69 }
70
71 Ok(())
72 }
73 }
74
75 pub fn give_from_isr(&self, context: &mut InterruptContext) -> bool {
77 unsafe { freertos_rs_give_semaphore_isr(self.semaphore, context.get_task_field_mut()) == 0 }
78 }
79
80 pub fn take_from_isr(&self, context: &mut InterruptContext) -> bool {
82 unsafe { freertos_rs_take_semaphore_isr(self.semaphore, context.get_task_field_mut()) == 0 }
83 }
84}
85
86impl Drop for Semaphore {
87 fn drop(&mut self) {
88 unsafe {
89 freertos_rs_delete_semaphore(self.semaphore);
90 }
91 }
92}
93
94pub struct SemaphoreGuard<'a> {
96 owner: &'a Semaphore,
97}
98
99impl<'a> Drop for SemaphoreGuard<'a> {
100 fn drop(&mut self) {
101 self.owner.give();
102 }
103}