From b2dadfd58097c85355dc867652ebe5ce883789a5 Mon Sep 17 00:00:00 2001 From: CaseySanchez Date: Mon, 30 Dec 2024 11:30:21 -0500 Subject: [PATCH] Support event groups --- freertos-rust/src/base.rs | 2 + freertos-rust/src/event_group.rs | 65 +++++++++++++++++++++++++++++++ freertos-rust/src/freertos/shim.c | 29 ++++++++++++++ freertos-rust/src/lib.rs | 4 ++ freertos-rust/src/shim.rs | 8 ++++ 5 files changed, 108 insertions(+) create mode 100644 freertos-rust/src/event_group.rs diff --git a/freertos-rust/src/base.rs b/freertos-rust/src/base.rs index a303928..09df5a9 100644 --- a/freertos-rust/src/base.rs +++ b/freertos-rust/src/base.rs @@ -23,11 +23,13 @@ pub type FreeRtosChar = u8; pub type FreeRtosBaseType = i32; pub type FreeRtosUBaseType = u32; pub type FreeRtosTickType = u32; +pub type FreeRtosEventBitsType = u32; pub type FreeRtosBaseTypeMutPtr = *mut FreeRtosBaseType; pub type FreeRtosTaskHandle = *const c_void; pub type FreeRtosQueueHandle = *const c_void; pub type FreeRtosSemaphoreHandle = *const c_void; +pub type FreeRtosEventGroupHandle = *const c_void; pub type FreeRtosTaskFunction = *const c_void; pub type FreeRtosTimerHandle = *const c_void; pub type FreeRtosTimerCallback = *const c_void; diff --git a/freertos-rust/src/event_group.rs b/freertos-rust/src/event_group.rs new file mode 100644 index 0000000..30354b7 --- /dev/null +++ b/freertos-rust/src/event_group.rs @@ -0,0 +1,65 @@ +use crate::base::*; +use crate::isr::*; +use crate::shim::*; +use crate::units::*; + +/// An event group +pub struct EventGroup { + event_group: FreeRtosEventGroupHandle, +} + +unsafe impl Send for EventGroup {} +unsafe impl Sync for EventGroup {} + +impl EventGroup { + /// Create a new event group + pub fn new() -> Result { + unsafe { + let s = freertos_rs_event_group_create(); + if s == 0 as *const _ { + return Err(FreeRtosError::OutOfMemory); + } + Ok(EventGroup { event_group: s }) + } + } + + /// # Safety + /// + /// `handle` must be a valid FreeRTOS event group handle. + #[inline] + pub unsafe fn from_raw_handle(handle: FreeRtosEventGroupHandle) -> Self { + Self { event_group: handle } + } + #[inline] + pub fn raw_handle(&self) -> FreeRtosEventGroupHandle { + self.event_group + } + + pub fn set_bits(&self, bits_to_set: FreeRtosEventBitsType) -> FreeRtosEventBitsType { + unsafe { freertos_rs_event_group_set_bits(self.event_group, bits_to_set) } + } + + pub fn get_bits(&self) -> FreeRtosEventBitsType { + unsafe { freertos_rs_event_group_get_bits(self.event_group) } + } + + pub fn clear_bits(&self, bits_to_clear: FreeRtosEventBitsType) -> FreeRtosEventBitsType { + unsafe { freertos_rs_event_group_clear_bits(self.event_group, bits_to_clear) } + } + + pub fn wait_bits(&self, bits_to_wait_for: FreeRtosEventBitsType, clear_on_exit: FreeRtosBaseType, wait_for_all_bits: FreeRtosBaseType, duration: D) -> FreeRtosEventBitsType { + unsafe { freertos_rs_event_group_wait_bits(self.event_group, bits_to_wait_for, clear_on_exit, wait_for_all_bits, duration.to_ticks()) } + } + + pub fn sync(&self, bits_to_set: FreeRtosEventBitsType, bits_to_wait_for: FreeRtosEventBitsType, duration: D) -> FreeRtosEventBitsType { + unsafe { freertos_rs_event_group_sync(self.event_group, bits_to_set, bits_to_wait_for, duration.to_ticks()) } + } +} + +impl Drop for EventGroup { + fn drop(&mut self) { + unsafe { + freertos_rs_event_group_delete(self.event_group); + } + } +} diff --git a/freertos-rust/src/freertos/shim.c b/freertos-rust/src/freertos/shim.c index 99a9240..c921e6d 100644 --- a/freertos-rust/src/freertos/shim.c +++ b/freertos-rust/src/freertos/shim.c @@ -10,6 +10,7 @@ STM32 example: #include "timers.h" #include "queue.h" #include "semphr.h" +#include "event_groups.h" // Just for testing void freertos_rs_invoke_configASSERT() { @@ -432,3 +433,31 @@ void freertos_rs_enter_critical() { void freertos_rs_exit_critical() { taskEXIT_CRITICAL(); } + +EventGroupHandle_t freertos_rs_event_group_create() { + return xEventGroupCreate(); +} + +void freertos_rs_event_group_delete(EventGroupHandle_t event_group) { + vEventGroupDelete(event_group); +} + +EventBits_t freertos_rs_event_group_set_bits(EventGroupHandle_t event_group, const EventBits_t bits_to_set) { + return xEventGroupSetBits(event_group, bits_to_set); +} + +EventBits_t freertos_rs_event_group_get_bits(EventGroupHandle_t event_group) { + return xEventGroupGetBits(event_group); +} + +EventBits_t freertos_rs_event_group_clear_bits(EventGroupHandle_t event_group, const EventBits_t bits_to_clear) { + return xEventGroupClearBits(event_group, bits_to_clear); +} + +EventBits_t freertos_rs_event_group_wait_bits(const EventGroupHandle_t event_group, const EventBits_t bits_to_wait_for, const BaseType_t clear_on_exit, const BaseType_t wait_for_all_bits, TickType_t ticks_to_wait) { + return xEventGroupWaitBits(event_group, bits_to_wait_for, clear_on_exit, wait_for_all_bits, ticks_to_wait); +} + +EventBits_t freertos_rs_event_group_sync(EventGroupHandle_t event_group, const EventBits_t bits_to_set, const EventBits_t bits_to_wait_for, TickType_t ticks_to_wait) { + return xEventGroupSync(event_group, bits_to_set, bits_to_wait_for, ticks_to_wait); +} diff --git a/freertos-rust/src/lib.rs b/freertos-rust/src/lib.rs index e645d73..9e8db53 100644 --- a/freertos-rust/src/lib.rs +++ b/freertos-rust/src/lib.rs @@ -83,6 +83,8 @@ mod mutex; mod queue; #[cfg(feature = "sync")] mod semaphore; +#[cfg(feature = "sync")] +mod event_group; #[cfg(any(feature = "time", feature = "sync"))] mod task; #[cfg(feature = "time")] @@ -116,6 +118,8 @@ pub use crate::mutex::*; pub use crate::queue::*; #[cfg(feature = "sync")] pub use crate::semaphore::*; +#[cfg(feature = "sync")] +pub use crate::event_group::*; #[cfg(any(feature = "time", feature = "sync"))] pub use crate::task::*; #[cfg(feature = "time")] diff --git a/freertos-rust/src/shim.rs b/freertos-rust/src/shim.rs index d4cdecc..813ba7f 100644 --- a/freertos-rust/src/shim.rs +++ b/freertos-rust/src/shim.rs @@ -168,4 +168,12 @@ extern "C" { pub fn freertos_rs_enter_critical(); pub fn freertos_rs_exit_critical(); + + pub fn freertos_rs_event_group_create() -> FreeRtosEventGroupHandle; + pub fn freertos_rs_event_group_delete(event_group: FreeRtosEventGroupHandle); + pub fn freertos_rs_event_group_set_bits(event_group: FreeRtosEventGroupHandle, bits_to_set: FreeRtosEventBitsType) -> FreeRtosEventBitsType; + pub fn freertos_rs_event_group_get_bits(event_group: FreeRtosEventGroupHandle) -> FreeRtosEventBitsType; + pub fn freertos_rs_event_group_clear_bits(event_group: FreeRtosEventGroupHandle, bits_to_clear: FreeRtosEventBitsType) -> FreeRtosEventBitsType; + pub fn freertos_rs_event_group_wait_bits(event_group: FreeRtosEventGroupHandle, bits_to_wait_for: FreeRtosEventBitsType, clear_on_exit: FreeRtosBaseType, wait_for_all_bits: FreeRtosBaseType, ticks_to_wait: FreeRtosTickType) -> FreeRtosEventBitsType; + pub fn freertos_rs_event_group_sync(event_group: FreeRtosEventGroupHandle, bits_to_set: FreeRtosEventBitsType, bits_to_wait_for: FreeRtosEventBitsType, ticks_to_wait: FreeRtosTickType) -> FreeRtosEventBitsType; }