Tasks running using TaskIF; with debug code

This commit is contained in:
Ulrich Mohr 2023-11-22 10:15:46 +01:00
parent f02e847ef1
commit e69e97eb4c

View File

@ -84,21 +84,28 @@ extern "C" fn rust_main() {
extern "C" fn task_entry(task_object: *mut cty::c_void) {
sifln!("Task Entry");
sifln!("running pointer {:p}", task_object);
let task: &mut PeriodicTask;
let task: &mut dyn TaskIF;
unsafe {
let pointer = task_object as *mut PeriodicTask;
task = &mut *pointer;
}
sifln!("running cast {:p}", task);
task.execute();
task.run();
}
trait ExecutableObjectIF {
fn perform(&mut self);
}
trait TaskIF {
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;
}
struct PeriodicTask<'a> {
stack_size: cty::size_t,
stack_size: cty::size_t, //TODO generic type and safety
task_handle: *const cty::c_void,
period: usize,
task_object: &'a mut dyn ExecutableObjectIF,
@ -114,37 +121,51 @@ impl<'a> PeriodicTask<'a> {
};
instance
}
}
fn execute(&mut self) {
impl<'a> TaskIF for PeriodicTask<'a> {
fn run(&mut self) {
sifln!("Task running {}", self.period);
loop {
self.task_object.perform();
unsafe {
task_delay(self.period as cty::uint32_t);
task_delay(self.period as cty::uint32_t); //TODO type of delay should be generic but safe (cap to max in C)
}
}
}
fn get_stack_size(&self) -> cty::size_t {
self.stack_size
}
fn set_handle(&mut self, task_handle: *const cty::c_void) {
self.task_handle = task_handle;
}
fn get_handle(&self) -> *const cty::c_void {
self.task_handle
}
}
struct TaskExecutor<'a> {
tasks: &'a mut [PeriodicTask<'a>],
tasks: &'a mut [&'a mut dyn TaskIF],
}
impl<'a> TaskExecutor<'a> {
fn run_tasks(&mut self) {
for task in self.tasks.iter_mut() {
// we give away a raw pointer, top be called by an OS task
// while this is generally very broke, we use a reference tied
// we give away a raw pointer, to be called by an OS task
// while this is generally very broken, we use a reference tied
// to our own lifetime and destroy the task when we get dropped
// 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;
sifln!("create task {:p}", task_pointer);
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 {
task.task_handle = create_task(task_entry, task_pointer, task.stack_size);
handle = create_task(task_entry, task_pointer, task.get_stack_size());
}
if task.task_handle == 0 as *mut cty::c_void {
if handle == 0 as *mut cty::c_void {
panic!("could not create Task");
} else {
task.set_handle(handle);
}
}
}
@ -154,7 +175,7 @@ impl<'a> Drop for TaskExecutor<'a> {
fn drop(&mut self) {
for task in self.tasks.iter_mut() {
unsafe {
delete_task(task.task_handle);
delete_task(task.get_handle());
}
}
}
@ -320,18 +341,27 @@ fn mission() {
};
let mut h2 = Handler {
id: 2,
// cycle: 0,
// other_handler: MessageQueueSender::<Message>::new(),
// cycle: 0,
// other_handler: MessageQueueSender::<Message>::new(),
};
// h2.other_handler = h1.command_queue.get_sender();
let t1: PeriodicTask = PeriodicTask::new(&mut h1, 512, 200);
let mut t1: PeriodicTask = PeriodicTask::new(&mut h1, 512, 200);
let t2: PeriodicTask = PeriodicTask::new(&mut h2, 512, 300);
let mut t2: PeriodicTask = PeriodicTask::new(&mut h2, 512, 300);
sifln!("t1 {:p}", &t1);
let mut task_executor = TaskExecutor{tasks: &mut [t1,t2]};
let r1: &mut dyn TaskIF = &mut t1;
sifln!("as dyn {:p}", r1);
let mut task_executor = TaskExecutor {
tasks: &mut [&mut t1, &mut t2],
};
sifln!("{:p}", task_executor.tasks[0]);
task_executor.run_tasks();
@ -339,7 +369,7 @@ fn mission() {
unsafe {
task_delay(2000);
}
sifln!("Mission delay2");
sifln!("executor dropped");
drop(task_executor);
//t2.period = 100; //Invalid
h1.id = 2;