freertos_rust/
queue.rs

1use crate::prelude::v1::*;
2use crate::base::*;
3use crate::shim::*;
4use crate::units::*;
5use crate::isr::*;
6
7unsafe impl<T: Sized + Copy> Send for Queue<T> {}
8unsafe impl<T: Sized + Copy> Sync for Queue<T> {}
9
10/// A queue with a finite size. The items are owned by the queue and are
11/// copied.
12#[derive(Debug)]
13pub struct Queue<T: Sized + Copy> {
14    queue: FreeRtosQueueHandle,
15    item_type: PhantomData<T>,
16}
17
18impl<T: Sized + Copy> Queue<T> {
19    pub fn new(max_size: usize) -> Result<Queue<T>, FreeRtosError> {
20
21        let item_size = mem::size_of::<T>();
22
23        let handle = unsafe { freertos_rs_queue_create(max_size as u32, item_size as u32) };
24
25        if handle == 0 as *const _ {
26            return Err(FreeRtosError::OutOfMemory);
27        }
28
29        Ok(Queue {
30            queue: handle,
31            item_type: PhantomData,
32        })
33    }
34
35    /// Send an item to the end of the queue. Wait for the queue to have empty space for it.
36    pub fn send<D: DurationTicks>(&self, item: T, max_wait: D) -> Result<(), FreeRtosError> {
37        unsafe {
38            if freertos_rs_queue_send(self.queue,
39                                      &item as *const _ as FreeRtosVoidPtr,
40                                      max_wait.to_ticks()) != 0 {
41                Err(FreeRtosError::QueueSendTimeout)
42            } else {
43                Ok(())
44            }
45        }
46    }
47
48    /// Send an item to the end of the queue, from an interrupt.
49    pub fn send_from_isr(&self,
50                         context: &mut InterruptContext,
51                         item: T)
52                         -> Result<(), FreeRtosError> {
53        unsafe {
54            if freertos_rs_queue_send_isr(self.queue,
55                                          &item as *const _ as FreeRtosVoidPtr,
56                                          context.get_task_field_mut()) != 0 {
57                Err(FreeRtosError::QueueFull)
58            } else {
59                Ok(())
60            }
61        }
62    }
63
64    /// Wait for an item to be available on the queue.
65    pub fn receive<D: DurationTicks>(&self, max_wait: D) -> Result<T, FreeRtosError> {
66        unsafe {
67            let mut buff = mem::zeroed::<T>();
68            let r = freertos_rs_queue_receive(self.queue,
69                                              &mut buff as *mut _ as FreeRtosMutVoidPtr,
70                                              max_wait.to_ticks());
71            if r == 0 {
72                return Ok(buff);
73            } else {
74                return Err(FreeRtosError::QueueReceiveTimeout);
75            }
76        }
77    }
78}
79
80impl<T: Sized + Copy> Drop for Queue<T> {
81    fn drop(&mut self) {
82        unsafe {
83            freertos_rs_queue_delete(self.queue);
84        }
85    }
86}