From 02d78e3c8b6ce1194809772081d223cd2060bb43 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Wed, 22 Nov 2023 11:37:57 +0100 Subject: [PATCH] queues initial version --- mission_rust/src/lib.rs | 82 ++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 138fb71..0c038be 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -2,6 +2,7 @@ //TODO look into using core::ffi (some types do not seem to work) //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_rules! sifln { @@ -48,6 +49,7 @@ fn panic(panic: &PanicInfo<'_>) -> ! { type TaskFunction = unsafe extern "C" fn(*mut cty::c_void); + extern "C" { fn outbyte(c: cty::c_char); //void *create_task(TaskFunction_t taskFunction, void *parameter, size_t stack_size) @@ -185,53 +187,53 @@ impl<'a> Drop for TaskExecutor<'a> { struct Handler { id: u32, - //command_queue: MessageQueue, + command_queue: MessageQueue, } struct HandlerSender { id: u32, cycle: u8, - //other_handler: MessageQueueSender, + other_handler: MessageQueueSender, } -// impl Handler { -// fn handle_message(&self, message: Message) { -// match message { -// Message::OK=> {sifln!("OK");}, -// Message::FAILED => {sifln!("FAILED");}, -// Message::DATA(data) => {sifln!("p1: {}, p2 {}", data.p1, data.p2);} -// } +impl Handler { + fn handle_message(&self, message: Message) { + match message { + Message::OK=> {sifln!("OK");}, + Message::FAILED => {sifln!("FAILED");}, + Message::DATA(data) => {sifln!("p1: {}, p2 {}", data.p1, data.p2);} + } -// } -// } + } +} impl ExecutableObjectIF for Handler { fn perform(&mut self) { sifln!("Handler {} performs", self.id); - // let result = self.command_queue.receive(); - // match result { - // Ok(message) => self.handle_message(message), - // Err(_) => {sifln!("Handler {} got nothing", self.id);} - // } + let result = self.command_queue.receive(); + match result { + Ok(message) => self.handle_message(message), + Err(_) => {sifln!("Handler {} got nothing", self.id);} + } } } impl ExecutableObjectIF for HandlerSender { fn perform(&mut self) { sifln!("HandlerSender {} performs step {}", self.id, self.cycle); - // match self.cycle { - // 0 => {let _ = self.other_handler.send(Message::OK);}, - // 1 => {let _ = self.other_handler.send(Message::FAILED);}, - // 2 => {let _ = self.other_handler.send(Message::DATA(GenericMessageData { p1: 1, p2: 2 }));}, - // _ => (), - // } - // self.cycle += 1; + match self.cycle { + 0 => {let _ = self.other_handler.send(Message::OK);}, + 1 => {let _ = self.other_handler.send(Message::FAILED);}, + 2 => {let _ = self.other_handler.send(Message::DATA(GenericMessageData { p1: 13, p2: 2 }));}, + _ => (), + } + self.cycle += 1; } } -/*struct MessageQueue { +struct MessageQueue { queue_id: *const cty::c_void, - buffer: [T; LENGTH], + _unused: Option, //need to constrain the queue to one message type for safety, but compiler needs that to be used } struct MessageQueueSender { @@ -239,17 +241,16 @@ struct MessageQueueSender { _unused: Option, //need to constrain the sender to one message type for safety, but compiler needs that to be used } -impl MessageQueue { - fn new() -> Self { +impl MessageQueue { + fn new(depth: usize) -> Self { let mut instance: Self; unsafe { instance = Self { 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 = - &mut instance.buffer as *mut _ as *mut cty::c_void; - instance.queue_id = create_queue(LENGTH, core::mem::size_of::(), buffer_pointer); + //TODO check cast of depth + instance.queue_id = create_queue(depth, core::mem::size_of::()); if instance.queue_id == 0 as *mut cty::c_void { panic!("could not create Queue"); @@ -267,10 +268,10 @@ impl MessageQueue { } fn receive(&self) -> Result { - let mut message: T; + let mut message: T = T::default(); let res: cty::uint8_t; 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; res = queue_receive(self.queue_id, message_pointer); } @@ -305,17 +306,16 @@ impl MessageQueueSender { } } -*/ - #[derive(Clone, Copy)] struct GenericMessageData { p1: u32, p2: u32, } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Default)] enum Message { OK, + #[default] FAILED, DATA(GenericMessageData), } @@ -339,15 +339,15 @@ fn mission() { let mut h1 = Handler { id: 1, - //command_queue: MessageQueue::new(), + command_queue: MessageQueue::new(5), }; - let mut h2 = Handler { + let mut h2 = HandlerSender { id: 2, - // cycle: 0, - // other_handler: MessageQueueSender::::new(), + cycle: 0, + other_handler: MessageQueueSender::::new(), }; - // h2.other_handler = h1.command_queue.get_sender(); + h2.other_handler = h1.command_queue.get_sender(); let mut t1: PeriodicTask = PeriodicTask { task_objects: &mut [&mut h1],