forked from ROMEO/obsw
Tasks running using TaskIF; with debug code
This commit is contained in:
parent
f02e847ef1
commit
e69e97eb4c
@ -84,21 +84,28 @@ extern "C" fn rust_main() {
|
|||||||
extern "C" fn task_entry(task_object: *mut cty::c_void) {
|
extern "C" fn task_entry(task_object: *mut cty::c_void) {
|
||||||
sifln!("Task Entry");
|
sifln!("Task Entry");
|
||||||
sifln!("running pointer {:p}", task_object);
|
sifln!("running pointer {:p}", task_object);
|
||||||
let task: &mut PeriodicTask;
|
let task: &mut dyn TaskIF;
|
||||||
unsafe {
|
unsafe {
|
||||||
let pointer = task_object as *mut PeriodicTask;
|
let pointer = task_object as *mut PeriodicTask;
|
||||||
task = &mut *pointer;
|
task = &mut *pointer;
|
||||||
}
|
}
|
||||||
sifln!("running cast {:p}", task);
|
sifln!("running cast {:p}", task);
|
||||||
task.execute();
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ExecutableObjectIF {
|
trait ExecutableObjectIF {
|
||||||
fn perform(&mut self);
|
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> {
|
struct PeriodicTask<'a> {
|
||||||
stack_size: cty::size_t,
|
stack_size: cty::size_t, //TODO generic type and safety
|
||||||
task_handle: *const cty::c_void,
|
task_handle: *const cty::c_void,
|
||||||
period: usize,
|
period: usize,
|
||||||
task_object: &'a mut dyn ExecutableObjectIF,
|
task_object: &'a mut dyn ExecutableObjectIF,
|
||||||
@ -114,37 +121,51 @@ impl<'a> PeriodicTask<'a> {
|
|||||||
};
|
};
|
||||||
instance
|
instance
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn execute(&mut self) {
|
impl<'a> TaskIF for PeriodicTask<'a> {
|
||||||
|
fn run(&mut self) {
|
||||||
sifln!("Task running {}", self.period);
|
sifln!("Task running {}", self.period);
|
||||||
loop {
|
loop {
|
||||||
self.task_object.perform();
|
self.task_object.perform();
|
||||||
unsafe {
|
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> {
|
struct TaskExecutor<'a> {
|
||||||
tasks: &'a mut [PeriodicTask<'a>],
|
tasks: &'a mut [&'a mut dyn TaskIF],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TaskExecutor<'a> {
|
impl<'a> TaskExecutor<'a> {
|
||||||
fn run_tasks(&mut self) {
|
fn run_tasks(&mut self) {
|
||||||
for task in self.tasks.iter_mut() {
|
for task in self.tasks.iter_mut() {
|
||||||
// we give away a raw pointer, top be called by an OS task
|
// we give away a raw pointer, to be called by an OS task
|
||||||
// while this is generally very broke, we use a reference tied
|
// while this is generally very broken, we use a reference tied
|
||||||
// to our own lifetime and destroy the task when we get dropped
|
// to our own lifetime and destroy the task when we get dropped
|
||||||
// this way, the reference is guaranteed to be valid over our
|
// this way, the reference is guaranteed to be valid over our
|
||||||
// lifetime while the task is deleted at the end of our lifetime
|
// 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;
|
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);
|
sifln!("create task {:p}", task_pointer);
|
||||||
|
let handle;
|
||||||
unsafe {
|
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");
|
panic!("could not create Task");
|
||||||
|
} else {
|
||||||
|
task.set_handle(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +175,7 @@ impl<'a> Drop for TaskExecutor<'a> {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
for task in self.tasks.iter_mut() {
|
for task in self.tasks.iter_mut() {
|
||||||
unsafe {
|
unsafe {
|
||||||
delete_task(task.task_handle);
|
delete_task(task.get_handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,18 +341,27 @@ fn mission() {
|
|||||||
};
|
};
|
||||||
let mut h2 = Handler {
|
let mut h2 = Handler {
|
||||||
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 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();
|
task_executor.run_tasks();
|
||||||
|
|
||||||
@ -339,7 +369,7 @@ fn mission() {
|
|||||||
unsafe {
|
unsafe {
|
||||||
task_delay(2000);
|
task_delay(2000);
|
||||||
}
|
}
|
||||||
sifln!("Mission delay2");
|
sifln!("executor dropped");
|
||||||
drop(task_executor);
|
drop(task_executor);
|
||||||
//t2.period = 100; //Invalid
|
//t2.period = 100; //Invalid
|
||||||
h1.id = 2;
|
h1.id = 2;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user