queues initial version

This commit is contained in:
2023-11-22 11:37:57 +01:00
parent cc7844d21d
commit 02d78e3c8b

View File

@ -2,6 +2,7 @@
//TODO look into using core::ffi (some types do not seem to work) //TODO look into using core::ffi (some types do not seem to work)
//TODO os errors in API calls //TODO os errors in API calls
//TODO look into a pattern for late initialized stuff, currently using Option (can we make it compile time safe?)
#[macro_export] #[macro_export]
macro_rules! sifln { macro_rules! sifln {
@ -48,6 +49,7 @@ fn panic(panic: &PanicInfo<'_>) -> ! {
type TaskFunction = unsafe extern "C" fn(*mut cty::c_void); type TaskFunction = unsafe extern "C" fn(*mut cty::c_void);
extern "C" { extern "C" {
fn outbyte(c: cty::c_char); fn outbyte(c: cty::c_char);
//void *create_task(TaskFunction_t taskFunction, void *parameter, size_t stack_size) //void *create_task(TaskFunction_t taskFunction, void *parameter, size_t stack_size)
@ -185,53 +187,53 @@ impl<'a> Drop for TaskExecutor<'a> {
struct Handler { struct Handler {
id: u32, id: u32,
//command_queue: MessageQueue<Message, 10>, command_queue: MessageQueue<Message>,
} }
struct HandlerSender { struct HandlerSender {
id: u32, id: u32,
cycle: u8, cycle: u8,
//other_handler: MessageQueueSender<Message>, other_handler: MessageQueueSender<Message>,
} }
// impl Handler { impl Handler {
// fn handle_message(&self, message: Message) { fn handle_message(&self, message: Message) {
// match message { match message {
// Message::OK=> {sifln!("OK");}, Message::OK=> {sifln!("OK");},
// Message::FAILED => {sifln!("FAILED");}, Message::FAILED => {sifln!("FAILED");},
// Message::DATA(data) => {sifln!("p1: {}, p2 {}", data.p1, data.p2);} Message::DATA(data) => {sifln!("p1: {}, p2 {}", data.p1, data.p2);}
// } }
// } }
// } }
impl ExecutableObjectIF for Handler { impl ExecutableObjectIF for Handler {
fn perform(&mut self) { fn perform(&mut self) {
sifln!("Handler {} performs", self.id); sifln!("Handler {} performs", self.id);
// let result = self.command_queue.receive(); let result = self.command_queue.receive();
// match result { match result {
// Ok(message) => self.handle_message(message), Ok(message) => self.handle_message(message),
// Err(_) => {sifln!("Handler {} got nothing", self.id);} Err(_) => {sifln!("Handler {} got nothing", self.id);}
// } }
} }
} }
impl ExecutableObjectIF for HandlerSender { impl ExecutableObjectIF for HandlerSender {
fn perform(&mut self) { fn perform(&mut self) {
sifln!("HandlerSender {} performs step {}", self.id, self.cycle); sifln!("HandlerSender {} performs step {}", self.id, self.cycle);
// match self.cycle { match self.cycle {
// 0 => {let _ = self.other_handler.send(Message::OK);}, 0 => {let _ = self.other_handler.send(Message::OK);},
// 1 => {let _ = self.other_handler.send(Message::FAILED);}, 1 => {let _ = self.other_handler.send(Message::FAILED);},
// 2 => {let _ = self.other_handler.send(Message::DATA(GenericMessageData { p1: 1, p2: 2 }));}, 2 => {let _ = self.other_handler.send(Message::DATA(GenericMessageData { p1: 13, p2: 2 }));},
// _ => (), _ => (),
// } }
// self.cycle += 1; self.cycle += 1;
} }
} }
/*struct MessageQueue<T, const LENGTH: usize> { struct MessageQueue<T> {
queue_id: *const cty::c_void, queue_id: *const cty::c_void,
buffer: [T; LENGTH], _unused: Option<T>, //need to constrain the queue to one message type for safety, but compiler needs that to be used
} }
struct MessageQueueSender<T> { struct MessageQueueSender<T> {
@ -239,17 +241,16 @@ struct MessageQueueSender<T> {
_unused: Option<T>, //need to constrain the sender to one message type for safety, but compiler needs that to be used _unused: Option<T>, //need to constrain the sender to one message type for safety, but compiler needs that to be used
} }
impl<T: Copy, const LENGTH: usize> MessageQueue<T, LENGTH> { impl<T: Default> MessageQueue<T> {
fn new() -> Self { fn new(depth: usize) -> Self {
let mut instance: Self; let mut instance: Self;
unsafe { unsafe {
instance = Self { instance = Self {
queue_id: 0 as *const cty::c_void, queue_id: 0 as *const cty::c_void,
buffer: [core::mem::MaybeUninit::zeroed().assume_init(); LENGTH], //Gets passed to C/FreeRTOS, so we never ever touch it ever again _unused: None
}; };
let buffer_pointer: *mut cty::c_void = //TODO check cast of depth
&mut instance.buffer as *mut _ as *mut cty::c_void; instance.queue_id = create_queue(depth, core::mem::size_of::<T>());
instance.queue_id = create_queue(LENGTH, core::mem::size_of::<T>(), buffer_pointer);
if instance.queue_id == 0 as *mut cty::c_void { if instance.queue_id == 0 as *mut cty::c_void {
panic!("could not create Queue"); panic!("could not create Queue");
@ -267,10 +268,10 @@ impl<T: Copy, const LENGTH: usize> MessageQueue<T, LENGTH> {
} }
fn receive(&self) -> Result<T, ()> { fn receive(&self) -> Result<T, ()> {
let mut message: T; let mut message: T = T::default();
let res: cty::uint8_t; let res: cty::uint8_t;
unsafe { unsafe {
message = core::mem::MaybeUninit::zeroed().assume_init(); // We only return it if the queue received something //message = core::mem::MaybeUninit::zeroed().assume_init(); // We only return it if the queue received something
let message_pointer: *mut cty::c_void = &mut message as *mut _ as *mut cty::c_void; let message_pointer: *mut cty::c_void = &mut message as *mut _ as *mut cty::c_void;
res = queue_receive(self.queue_id, message_pointer); res = queue_receive(self.queue_id, message_pointer);
} }
@ -305,17 +306,16 @@ impl<T> MessageQueueSender<T> {
} }
} }
*/
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
struct GenericMessageData { struct GenericMessageData {
p1: u32, p1: u32,
p2: u32, p2: u32,
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone, Default)]
enum Message { enum Message {
OK, OK,
#[default]
FAILED, FAILED,
DATA(GenericMessageData), DATA(GenericMessageData),
} }
@ -339,15 +339,15 @@ fn mission() {
let mut h1 = Handler { let mut h1 = Handler {
id: 1, id: 1,
//command_queue: MessageQueue::new(), command_queue: MessageQueue::new(5),
}; };
let mut h2 = Handler { let mut h2 = HandlerSender {
id: 2, id: 2,
// cycle: 0, cycle: 0,
// other_handler: MessageQueueSender::<Message>::new(), other_handler: MessageQueueSender::<Message>::new(),
}; };
// h2.other_handler = h1.command_queue.get_sender(); h2.other_handler = h1.command_queue.get_sender();
let mut t1: PeriodicTask = PeriodicTask { let mut t1: PeriodicTask = PeriodicTask {
task_objects: &mut [&mut h1], task_objects: &mut [&mut h1],