Tasks

In Drone OS applications, a task is a logical unit of work. Most often it's represented as an async function that's running in a separate thread. By convention, each task is placed into a separate module inside src/tasks directory. The module contains at least a task main function named handler. The function then re-exported in src/tasks/mod.rs like this:


#![allow(unused)]
fn main() {
pub mod my_task;

pub use self::my_task::handler as my_task;
}

It is common to use an unused interrupt as the task thread. For example, in STM32F103, there is "UART5 global interrupt" at the position 53. If UART5 peripheral is not used by the application, its interrupt can be reused for a completely different task:


#![allow(unused)]
fn main() {
thr::nvic! {
    // ... The header is skipped ...

    threads => {
        exceptions => {
            /// All classes of faults.
            pub hard_fault;
        };
        interrupts => {
            /// A thread for `my_task`.
            53: pub my_task;
        };
    };
}
}

Then, assuming my_task is an async function, the thread can run the task as follows:


#![allow(unused)]
fn main() {
use crate::tasks;
use drone_cortexm::thr::prelude::*;

thr.my_task.enable_int();
thr.my_task.set_priority(0xB0);
thr.my_task.exec(tasks::my_task());
}

Now, whenever my_task future or any of its nested futures returns Poll::Pending, the thread suspends. And it will be resumed when the future will be ready for polling again. It is implemented by passing a core::task::Waker behind the scenes, which will trigger the thread when waked.