multi object periodic task

This commit is contained in:
Ulrich Mohr 2023-11-22 10:42:55 +01:00
parent e69e97eb4c
commit cc7844d21d

View File

@ -76,20 +76,16 @@ extern "C" {
extern "C" fn rust_main() {
sifln!("Rust startup 🚀");
mission();
sifln!("Mission done");
}
#[no_mangle]
extern "C" fn task_entry(task_object: *mut cty::c_void) {
sifln!("Task Entry");
sifln!("running pointer {:p}", task_object);
let task: &mut dyn TaskIF;
unsafe {
let pointer = task_object as *mut PeriodicTask;
task = &mut *pointer;
}
sifln!("running cast {:p}", task);
task.run();
}
@ -108,26 +104,33 @@ struct PeriodicTask<'a> {
stack_size: cty::size_t, //TODO generic type and safety
task_handle: *const cty::c_void,
period: usize,
task_object: &'a mut dyn ExecutableObjectIF,
task_objects: &'a mut [&'a mut dyn ExecutableObjectIF],
}
impl<'a> PeriodicTask<'a> {
fn new(object: &'a mut dyn ExecutableObjectIF, stack_size: usize, period: usize) -> Self {
let instance = Self {
stack_size: stack_size,
task_handle: 0 as *const cty::c_void,
period: period,
task_object: object,
};
instance
}
}
// TODO Passing the slice does not work, find out why...
// impl<'a> PeriodicTask<'a> {
// fn new(
// objects: &'a mut [&'a mut dyn ExecutableObjectIF],
// stack_size: usize,
// period: usize,
// ) -> Self {
// let instance = Self {
// stack_size: stack_size,
// task_handle: 0 as *const cty::c_void,
// period: period,
// task_objects: objects,
// };
// instance
// }
// }
impl<'a> TaskIF for PeriodicTask<'a> {
fn run(&mut self) {
sifln!("Task running {}", self.period);
loop {
self.task_object.perform();
for object in self.task_objects.iter_mut() {
object.perform();
}
//TODO make this exact
unsafe {
task_delay(self.period as cty::uint32_t); //TODO type of delay should be generic but safe (cap to max in C)
}
@ -157,10 +160,9 @@ impl<'a> TaskExecutor<'a> {
// this way, the reference is guaranteed to be valid over our
// lifetime while the task is deleted at the end of our lifetime
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??
sifln!("create task {:p}", task_pointer);
let handle;
unsafe {
handle = create_task(task_entry, task_pointer, task.get_stack_size());
handle = create_task(task_entry, task_pointer, task.get_stack_size());
}
if handle == 0 as *mut cty::c_void {
panic!("could not create Task");
@ -347,15 +349,19 @@ fn mission() {
// h2.other_handler = h1.command_queue.get_sender();
let mut t1: PeriodicTask = PeriodicTask::new(&mut h1, 512, 200);
let mut t1: PeriodicTask = PeriodicTask {
task_objects: &mut [&mut h1],
stack_size: 512,
period: 200,
task_handle: 0 as *const cty::c_void,
};
let mut t2: PeriodicTask = PeriodicTask::new(&mut h2, 512, 300);
sifln!("t1 {:p}", &t1);
let r1: &mut dyn TaskIF = &mut t1;
sifln!("as dyn {:p}", r1);
let mut t2: PeriodicTask = PeriodicTask {
task_objects: &mut [&mut h2],
stack_size: 512,
period: 400,
task_handle: 0 as *const cty::c_void,
};
let mut task_executor = TaskExecutor {
tasks: &mut [&mut t1, &mut t2],
@ -371,8 +377,6 @@ fn mission() {
}
sifln!("executor dropped");
drop(task_executor);
//t2.period = 100; //Invalid
h1.id = 2;
unsafe {
task_delay(2000);
}