diff --git a/mission_rust/src/fsrc/mod.rs b/mission_rust/src/fsrc/mod.rs index 1ba25a8..22b2765 100644 --- a/mission_rust/src/fsrc/mod.rs +++ b/mission_rust/src/fsrc/mod.rs @@ -1,4 +1,5 @@ pub mod sif; pub mod queues; pub mod osal; -pub mod tasks; \ No newline at end of file +pub mod tasks; +pub mod objectmanager; \ No newline at end of file diff --git a/mission_rust/src/fsrc/objectmanager.rs b/mission_rust/src/fsrc/objectmanager.rs new file mode 100644 index 0000000..50b2d8e --- /dev/null +++ b/mission_rust/src/fsrc/objectmanager.rs @@ -0,0 +1,12 @@ +use super::tasks::ExecutableObjectIF; + +pub type ObjectId = usize; +pub trait ObjectManager<'a> { + fn get_object(&self, id: ObjectId) -> Option<&'a dyn SystemObject>; +} + +pub trait SystemObject: ExecutableObjectIF { + fn get_id(&self) -> ObjectId; + fn initialize(&mut self, object_manager: &dyn ObjectManager) -> Result<(),()>; + fn get_command_queue(&self) -> crate::fsrc::queues::MessageQueueSender; +} \ No newline at end of file diff --git a/mission_rust/src/fsrc/queues/mod.rs b/mission_rust/src/fsrc/queues/mod.rs index cd78616..950a567 100644 --- a/mission_rust/src/fsrc/queues/mod.rs +++ b/mission_rust/src/fsrc/queues/mod.rs @@ -1,23 +1,20 @@ -pub struct MessageQueue { +pub struct MessageQueue { queue_id: *const cty::c_void, - _unused: Option, //need to constrain the queue to one message type for safety, but compiler needs that to be used } -pub struct MessageQueueSender { +pub struct MessageQueueSender { queue_id: Option<*const cty::c_void>, - _unused: Option, //need to constrain the sender to one message type for safety, but compiler needs that to be used } -impl MessageQueue { +impl MessageQueue { pub fn new(depth: usize) -> Self { let mut instance: Self; unsafe { instance = Self { queue_id: 0 as *const cty::c_void, - _unused: None, - }; + }; //TODO check cast of depth - instance.queue_id = crate::fsrc::osal::create_queue(depth, core::mem::size_of::()); + instance.queue_id = crate::fsrc::osal::create_queue(depth, core::mem::size_of::()); if instance.queue_id == 0 as *mut cty::c_void { panic!("could not create Queue"); @@ -26,16 +23,15 @@ impl MessageQueue { } } - pub fn get_sender(&self) -> MessageQueueSender { - let instance: MessageQueueSender = MessageQueueSender:: { + pub fn get_sender(&self) -> MessageQueueSender { + let instance: MessageQueueSender = MessageQueueSender { queue_id: Some(self.queue_id), - _unused: None, }; instance } - pub fn receive(&self) -> Result { - let mut message: T = T::default(); + pub fn receive(&self) -> Result { + let mut message: Message = Message::default(); let res: cty::uint8_t; unsafe { //message = core::mem::MaybeUninit::zeroed().assume_init(); // We only return it if the queue received something @@ -50,15 +46,14 @@ impl MessageQueue { } } -impl MessageQueueSender { +impl MessageQueueSender { pub fn new() -> Self { Self { queue_id: None, - _unused: None, - } + } } - pub fn send(&self, message: T) -> Result<(), ()> { + pub fn send(&self, message: Message) -> Result<(), ()> { let queue_id = self.queue_id.expect("unitialized Message Queue"); let res: cty::uint8_t; unsafe { diff --git a/mission_rust/src/fsrc/tasks/mod.rs b/mission_rust/src/fsrc/tasks/mod.rs index 878540c..d3460e3 100644 --- a/mission_rust/src/fsrc/tasks/mod.rs +++ b/mission_rust/src/fsrc/tasks/mod.rs @@ -1,3 +1,7 @@ +use core::slice; + +use super::objectmanager::ObjectManager; + #[no_mangle] extern "C" fn task_entry(task_object: *mut cty::c_void) { let task: &mut dyn TaskIF; @@ -12,23 +16,25 @@ pub trait ExecutableObjectIF { fn perform(&mut self); } -pub trait TaskIF { +pub trait TaskIF<'a> { fn run(&mut self); fn get_stack_size(&self) -> cty::size_t; fn set_handle(&mut self, task_handle: *const cty::c_void); fn get_handle(&self) -> *const cty::c_void; + fn get_objects(&'a self) -> &'a [&'a mut dyn crate::objectmanager::SystemObject]; + fn initialize(&mut self, object_manager: &dyn ObjectManager) -> Result<(), ()>; } pub struct PeriodicTask<'a> { pub stack_size: cty::size_t, //TODO generic type and safety pub task_handle: *const cty::c_void, pub period: usize, - pub task_objects: &'a mut [&'a mut dyn ExecutableObjectIF], + pub task_objects: &'a mut [&'a mut dyn crate::objectmanager::SystemObject], } impl<'a> PeriodicTask<'a> { pub fn new( - objects: &'a mut [&'a mut dyn ExecutableObjectIF], + objects: &'a mut [&'a mut dyn crate::objectmanager::SystemObject], stack_size: usize, period: usize, ) -> PeriodicTask<'a> { @@ -42,7 +48,7 @@ impl<'a> PeriodicTask<'a> { } } -impl<'a> TaskIF for PeriodicTask<'a> { +impl<'a> TaskIF<'a> for PeriodicTask<'a> { fn run(&mut self) { loop { for object in self.task_objects.iter_mut() { @@ -63,14 +69,34 @@ impl<'a> TaskIF for PeriodicTask<'a> { fn get_handle(&self) -> *const cty::c_void { self.task_handle } + fn get_objects(&'a self) -> &'a [&'a mut dyn crate::objectmanager::SystemObject] { + self.task_objects + } + fn initialize(&mut self, object_manager: &dyn ObjectManager) -> Result<(), ()> { + for object in self.task_objects.iter_mut() { + let result = object.initialize(object_manager); + match result { + Ok(()) => continue, + Err(()) => return Err(()), + } + } + Ok(()) + } } pub struct TaskExecutor<'a> { - pub tasks: &'a mut [&'a mut dyn TaskIF], + pub tasks: &'a mut [&'a mut dyn TaskIF<'a>], } impl<'a> TaskExecutor<'a> { pub fn run_tasks(&mut self) { + let object_manager = TaskObjectManager { + tasks: unsafe { slice::from_raw_parts(self.tasks.as_ptr(), self.tasks.len()) }, + }; + for task in self.tasks.iter_mut() { + let _ = task.initialize(&object_manager); + } + drop(object_manager); for task in self.tasks.iter_mut() { // we give away a raw pointer, to be called by an OS task // while this is generally very broken, we use a reference tied @@ -80,7 +106,8 @@ impl<'a> TaskExecutor<'a> { let task_pointer: *const cty::c_void = *task as *mut _ as *const cty::c_void; //TODO this does work without the "*" in front of the task -> Why?? let handle; unsafe { - handle = crate::fsrc::osal::create_task(task_entry, task_pointer, task.get_stack_size()); + handle = + crate::fsrc::osal::create_task(task_entry, task_pointer, task.get_stack_size()); } if handle == 0 as *mut cty::c_void { panic!("could not create Task"); @@ -91,6 +118,26 @@ impl<'a> TaskExecutor<'a> { } } +struct TaskObjectManager<'a> { + tasks: &'a [&'a mut dyn TaskIF<'a>], +} + +impl<'a> crate::objectmanager::ObjectManager<'a> for TaskObjectManager<'a> { + fn get_object( + &self, + id: crate::objectmanager::ObjectId, + ) -> Option<&'a dyn crate::objectmanager::SystemObject> { + for task in self.tasks.iter() { + for object in task.get_objects().iter() { + if object.get_id() == id { + return Some(*object); + } + } + } + None + } +} + impl<'a> Drop for TaskExecutor<'a> { fn drop(&mut self) { for task in self.tasks.iter_mut() { @@ -99,4 +146,4 @@ impl<'a> Drop for TaskExecutor<'a> { } } } -} \ No newline at end of file +} diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 68bd7d8..ae16d89 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -6,10 +6,10 @@ mod fsrc; -use core::mem::size_of; -use core::panic::PanicInfo; use core::fmt::Write; +use core::panic::PanicInfo; +use fsrc::objectmanager::SystemObject; use fsrc::*; #[panic_handler] @@ -33,8 +33,6 @@ fn panic(panic: &PanicInfo<'_>) -> ! { loop {} } - - #[no_mangle] extern "C" fn rust_main() { sifln!("Rust startup 🚀"); @@ -42,16 +40,16 @@ extern "C" fn rust_main() { sifln!("Mission done"); } - struct Handler { - id: u32, - command_queue: queues::MessageQueue, + id: objectmanager::ObjectId, + command_queue: queues::MessageQueue, } struct HandlerSender { - id: u32, + id: objectmanager::ObjectId, + other_handler: objectmanager::ObjectId, cycle: u8, - other_handler: queues::MessageQueueSender, + other_handler_queue: queues::MessageQueueSender, } impl Handler { @@ -88,15 +86,15 @@ impl tasks::ExecutableObjectIF for HandlerSender { sifln!("HandlerSender {} performs step {}", self.id, self.cycle); match self.cycle { 0 => { - let _ = self.other_handler.send(queues::Message::OK); + let _ = self.other_handler_queue.send(queues::Message::OK); } 1 => { - let _ = self.other_handler.send(queues::Message::FAILED); + let _ = self.other_handler_queue.send(queues::Message::FAILED); } 2 => { - let _ = self - .other_handler - .send(queues::Message::DATA(queues::GenericMessageData { p1: 13, p2: 2 })); + let _ = self.other_handler_queue.send(queues::Message::DATA( + queues::GenericMessageData { p1: 13, p2: 2 }, + )); } _ => (), } @@ -104,6 +102,34 @@ impl tasks::ExecutableObjectIF for HandlerSender { } } +impl SystemObject for Handler { + fn get_command_queue(&self) -> crate::fsrc::queues::MessageQueueSender { + self.command_queue.get_sender() + } + fn get_id(&self) -> objectmanager::ObjectId { + self.id + } + fn initialize(&mut self, _object_manager: &dyn objectmanager::ObjectManager) -> Result<(), ()> { + Ok(()) + } +} + +impl SystemObject for HandlerSender { + fn get_command_queue(&self) -> crate::fsrc::queues::MessageQueueSender { + queues::MessageQueueSender::new() + } + fn get_id(&self) -> objectmanager::ObjectId { + self.id + } + fn initialize(&mut self, object_manager: &dyn objectmanager::ObjectManager) -> Result<(), ()> { + let other_handler = object_manager.get_object(self.other_handler); + match other_handler { + Some(other) => self.other_handler_queue = other.get_command_queue(), + None => return Err(()), + } + Ok(()) + } +} fn mission() { sifln!("Mission enter"); @@ -114,13 +140,12 @@ fn mission() { }; let mut h2 = HandlerSender { id: 2, + other_handler: 1, cycle: 0, - other_handler: queues::MessageQueueSender::::new(), + other_handler_queue: queues::MessageQueueSender::new(), }; - h2.other_handler = h1.command_queue.get_sender(); - - let array: &mut [&mut dyn tasks::ExecutableObjectIF] = &mut [&mut h1]; + let array: &mut [&mut dyn objectmanager::SystemObject] = &mut [&mut h1]; let mut t1 = tasks::PeriodicTask::new(array, 512, 200); @@ -131,16 +156,10 @@ fn mission() { task_handle: 0 as *const cty::c_void, }; - let _i = 1; - - sifln!("sizeof {}, pointer struct {:p}, pointer element {:p}, next element{:p}", size_of::(), &t2, t2.task_objects, &_i); - let mut task_executor = tasks::TaskExecutor { tasks: &mut [&mut t1, &mut t2], }; - sifln!("{:p}", task_executor.tasks[0]); - task_executor.run_tasks(); sifln!("Mission delay");