Bare Metal Programming Tool Kit
|
an independent thread of execution More...
#include <rtos.h>
Public Member Functions | |
task (unsigned int priority=BMPTK_RTOS_MAX_PRIORITY, const char *tname="", unsigned int stacksize=BMPTK_RTOS_DEFAULT_STACK_SIZE) | |
constructor, specify priority, name and stacksize | |
virtual | ~task () |
throws an error, beacuse tasks should never be destroyed | |
void | release () |
release the CPU to the scheduler | |
unsigned int | priority () const |
report the task priority | |
const char * | name () const |
report the task name | |
bool | is_ready () const |
report whether the task is currently ready for execution | |
bool | is_blocked () const |
report whether the task is currently blocked | |
void | print (std::ostream &stream, bool header=true) const |
print task statistics | |
event | wait () |
wait for all waitables created for this task | |
event | wait (const waitable &w) |
wait for a single waitable | |
event | wait (const event &set) |
wait for a set of waitables | |
void | set (flag &w) |
set a flag | |
void | ignore_activation_time () |
ignore this activation for the statistics | |
Protected Member Functions | |
virtual void | main ()=0 |
task body, must be provided by a derived concrete class | |
Friends | |
class | periodic_task |
class | waitable_set |
class | flag |
class | waitable |
class | mutex |
void | task_trampoline () |
void | sleep_until (time t) |
void | print (std::ostream &stream) |
prints statistics about the tasks to the stream. | |
void | do_statistics_clear () |
void | add (task *new_task) |
void | beat () |
an independent thread of execution
A task is an independent thread of execution, using its own stack. Tasks share the single CPU, so only one task can be running at any time. The rtos determines which task is running. A task has two states: runnable and blocked. When a task is created it is runnable.
All tasks (and the rtos code itself) run in the same memory space, without protection from each other. Hence a 'wild pointer' in one task can destroy data in another task, or even in the rtos.
Each task is created with a fixed priority, which can be any unsigend integer value below BMPTK_RTOS_MAX_PRIORITY (by default 10_000). After creation the priority can not be changed. The value 0 indicates the highest task priority, a higher number indicates a lower priority. Each task must have a unqiue priority, it is an error to create a task with same priority as an existing task. You can omit the priority, in which case the rtos will select an unused priority starting at BMPTK_RTOS_MAX_PRIORITY (in other words, it will choose a low priority for your task).
Each task has its own stack. You can specify the size of the stack at task creation. If you omit the stack size, BMPTK_RTOS_DEFAULT_STACK_SIZE will be used (default: 2 Kb). This will be enough for most tasks, if you take care not to allocate big things on the stack, and avoid very deep nesting (watch out for recursion!).
A task is created by instantiating a class that derives from rtos::task and supplies a main(). This main() should never return. The fragment below shows how you can do this. The task name is used for statistics and debugging. As shown for the name, it might be wise to get the task parameters as arguments to the constructor of your task.
code
The example below is a complete program that shows the standard part (initialization, and a main that calls rtos::run()), a function for writing to an individual LED, a task class that blinks a LED, and two instatiations of this class.
Subseqent examples will not show the standard initialization (the part up to the comment line).
code
bmptk::rtos::task::task | ( | unsigned int | priority = BMPTK_RTOS_MAX_PRIORITY , |
const char * | tname = "" , |
||
unsigned int | stacksize = BMPTK_RTOS_DEFAULT_STACK_SIZE |
||
) |
constructor, specify priority, name and stacksize
Priorities are reasonably-valued (below BMPTK_RTOS_DEFAULT_RIORITY) unsigned integers. 0 is te highest priority. Priorities must be unqiue. The default causes the constructor to choose a free priority starting at BMPTK_RTOS_DEFAULT_PRIORITY (default: 10000).
The name is used for debugging and statistics.
A stack of stack_size bytes is allocated for the task. The default is 2 kB.
|
inline |
ignore this activation for the statistics
Calling this function makes the rtos statistics ignore the current task activation as far as statistics is concerned. You can use this to avoid pullution of your task statistics with the timing effects of debug logging. But make sure you don't use it in the 'normal' execution paths, becaue that would make the statitics lie to you.
|
protectedpure virtual |
task body, must be provided by a derived concrete class
A task is created by inheriting from task and providing a main() function. Initialisation of the task, including creating its waitables, should be done in the constructor. Don't forget to call the constructor of the task class!
The main() is the body of the task. It should never terminate.
Each task has a unique priority (an unsigned integer). A lower value indicates a higher priority. The rtos scheduler will always run the task with the higest-priority runnable (neither blocked nor suspended) task. A task runs until it changes this 'situation' by using an rtos call that changes its own state to not runnable, or the state of a higher priority task to runnable.
Timers are served only when the rtos is activated by calling any of its state-changing interfaces. Hence the longest run time between such calls determines the granularity (timewise responsiveness) of the application. Within a timeconsuming computation a task can call release() to have the rtos serve the timers.
void bmptk::rtos::task::release | ( | ) |
release the CPU to the scheduler
Sevices timers and releases the CPU to a higher priority task if one became ready.
|
inline |
wait for all waitables created for this task
Wait (prevent execution) until at least one of the waitables is set. Return and clear that waitable. Three variants for the parameter:
It is an error to wait for waitables that have not been created for this task.
wait for a single waitable
Wait (prevent execution) until at least one of the waitables is set. Return and clear that waitable. Three variants for the parameter:
wait for a set of waitables
Wait (prevent execution) until at least one of the waitables is set. Return and clear that waitable. Three variants for the parameter: