freertos_rust/
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 pub fn new_counting(max: u32, initial: u32) -> Result<Semaphore, FreeRtosError> {
28 unsafe {
29 let s = freertos_rs_create_counting_semaphore(max, initial);
30 if s == 0 as *const _ {
31 return Err(FreeRtosError::OutOfMemory);
32 }
33 Ok(Semaphore { semaphore: s })
34 }
35 }
36
37 #[inline]
44 pub unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self {
45 Self { semaphore: handle }
46 }
47 #[inline]
48 pub fn raw_handle(&self) -> FreeRtosSemaphoreHandle {
49 self.semaphore
50 }
51
52 pub fn lock<D: DurationTicks>(&self, max_wait: D) -> Result<SemaphoreGuard<'_>, FreeRtosError> {
54 self.take(max_wait).map(|()| SemaphoreGuard { owner: self })
55 }
56
57 pub fn give(&self) -> bool {
59 unsafe { freertos_rs_give_semaphore(self.semaphore) == 0 }
60 }
61
62 pub fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError> {
63 unsafe {
64 let res = freertos_rs_take_semaphore(self.semaphore, max_wait.to_ticks());
65
66 if res != 0 {
67 return Err(FreeRtosError::Timeout);
68 }
69
70 Ok(())
71 }
72 }
73
74 pub fn give_from_isr(&self, context: &mut InterruptContext) -> bool {
76 unsafe { freertos_rs_give_semaphore_isr(self.semaphore, context.get_task_field_mut()) == 0 }
77 }
78
79 pub fn take_from_isr(&self, context: &mut InterruptContext) -> bool {
81 unsafe { freertos_rs_take_semaphore_isr(self.semaphore, context.get_task_field_mut()) == 0 }
82 }
83}
84
85impl Drop for Semaphore {
86 fn drop(&mut self) {
87 unsafe {
88 freertos_rs_delete_semaphore(self.semaphore);
89 }
90 }
91}
92
93pub struct SemaphoreGuard<'a> {
95 owner: &'a Semaphore,
96}
97
98impl<'a> Drop for SemaphoreGuard<'a> {
99 fn drop(&mut self) {
100 self.owner.give();
101 }
102}