osal_rs/freertos/
semaphore.rs1use core::fmt::{Debug, Display};
21use core::ops::Deref;
22use core::ptr::null_mut;
23
24use super::ffi::{SemaphoreHandle, pdFAIL, pdFALSE};
25use super::system::System;
26use super::types::{BaseType, UBaseType};
27use crate::traits::{SemaphoreFn, SystemFn, ToTick};
28use crate::utils::{Error, Result, OsalRsBool};
29use crate::{vSemaphoreDelete, xSemaphoreCreateCounting, xSemaphoreGive, xSemaphoreGiveFromISR, xSemaphoreTake, xSemaphoreTakeFromISR};
30
31pub struct Semaphore (SemaphoreHandle);
32
33unsafe impl Send for Semaphore {}
34unsafe impl Sync for Semaphore {}
35
36
37impl SemaphoreFn for Semaphore {
38 fn new(max_count: UBaseType, initial_count: UBaseType) -> Result<Self> {
39 let handle = xSemaphoreCreateCounting!(max_count, initial_count);
40 if handle.is_null() {
41 Err(Error::OutOfMemory)
42 } else {
43 Ok(Self (handle))
44 }
45 }
46
47 fn new_with_count(initial_count: UBaseType) -> Result<Self> {
48 let handle = xSemaphoreCreateCounting!(UBaseType::MAX, initial_count);
49 if handle.is_null() {
50 Err(Error::OutOfMemory)
51 } else {
52 Ok(Self (handle))
53 }
54 }
55
56 fn wait(&self, ticks_to_wait: impl ToTick) -> OsalRsBool {
57 if xSemaphoreTake!(self.0, ticks_to_wait.to_ticks()) != pdFAIL {
58 OsalRsBool::True
59 } else {
60 OsalRsBool::False
61 }
62 }
63
64 fn wait_from_isr(&self) -> OsalRsBool {
65 let mut higher_priority_task_woken: BaseType = pdFALSE;
66 if xSemaphoreTakeFromISR!(self.0, &mut higher_priority_task_woken) != pdFAIL {
67
68 System::yield_from_isr(higher_priority_task_woken);
69
70 OsalRsBool::True
71 } else {
72
73 OsalRsBool::False
74 }
75 }
76
77 fn signal(&self) -> OsalRsBool {
78 if xSemaphoreGive!(self.0) != pdFAIL {
79 OsalRsBool::True
80 } else {
81 OsalRsBool::False
82 }
83 }
84
85 fn signal_from_isr(&self) -> OsalRsBool {
86 let mut higher_priority_task_woken: BaseType = pdFALSE;
87 if xSemaphoreGiveFromISR!(self.0, &mut higher_priority_task_woken) != pdFAIL {
88
89 System::yield_from_isr(higher_priority_task_woken);
90
91 OsalRsBool::True
92 } else {
93 OsalRsBool::False
94 }
95 }
96
97 fn delete(&mut self) {
98 vSemaphoreDelete!(self.0);
99 self.0 = null_mut();
100 }
101
102
103}
104
105
106impl Drop for Semaphore {
107 fn drop(&mut self) {
108 if self.0.is_null() {
109 return;
110 }
111 self.delete();
112 }
113}
114
115impl Deref for Semaphore {
116 type Target = SemaphoreHandle;
117
118 fn deref(&self) -> &Self::Target {
119 &self.0
120 }
121}
122
123impl Debug for Semaphore {
124 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
125 f.debug_struct("Semaphore")
126 .field("handle", &self.0)
127 .finish()
128 }
129}
130
131impl Display for Semaphore {
132 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
133 write!(f, "Semaphore {{ handle: {:?} }}", self.0)
134 }
135}