Task Library
What Energia Does
Energia considers each sketch as a task with two functions: initial setup() and to-be-repeated loop().
Energia performs some under-the-hood work: it runs the function setup() once and includes the loop() function inside an endless loop. |
xdc_Void the_task(xdc_UArg _task_setup, xdc_UArg _task_loop) { /* Call setup once */ (*(void(*)()) _task_setup)();
/* Call loop repeatedly */ for(;;) { (*(void(*)()) _task_loop)(); System_flush(); Task_yield(); } } |
Let's Try
The rtosGlobals.h header includes the standard libraries and defines the task myTask and the timer myTimer, required by the third solution only.
The mains ketch can be kept with empty setup() and loop() functions. |
/// /// @author Rei Vilo /// @date Jun 23, 2015 10:32 /// @version 101 /// /// @copyright (c) Rei Vilo, 2015 /// @copyright CC = BY SA NC /// // Core library #include "Energia.h" // Include application, user and local libraries #include "Task.h" #include "Timer.h" // Define variables and constants Task myTask; Timer myTimer; uint8_t valueB = 0; |
First Solution
The first solution is very similar to the standard implementation of the tasks as sketches by Energia, where the function is included in an endless loop.
Note that the initialisation of the port is done in the rtosSetup() function. myTask.begin() defines the function to be called, sets the priority and runs the function once. The priority is a value between 0 and Task_numPriorities -1. Task_numPriorities is a constant provided by RTOS, which value is 16 or 32 and depends on the system. |
void functionTask() { // Solution 1: with loop, works fine while (true) { valueB = 1 - valueB; digitalWrite(BLUE_LED, valueB); delay(333); } } // Add optional rtosSetup function void rtosSetup() { pinMode(BLUE_LED, OUTPUT); myTask.begin(functionTask, Task_numPriorities - 1); } |
Second Solution Doesn't Work
The second solution doesn't work, as the function functionTask() doesn't include any endless loop.
Because the task is scheduled only once by myTask.begin(), it runs only once. |
void functionTask() { // Solution 2: with delay, doesn't work valueB = 1 - valueB; digitalWrite(BLUE_LED, valueB); delay(333); } // Add optional rtosSetup function void rtosSetup() { pinMode(BLUE_LED, OUTPUT); myTask.begin(functionTask, Task_numPriorities - 1); } |
Third and Best Solution
The third and last solution is the cleanest one.
The function functionTask() only toggles the value LED and is called by the timer myTimer every 333 ms. |
void functionTask() { // Solution 3: with Timer, works fine valueB = 1 - valueB; digitalWrite(BLUE_LED, valueB); } // Add optional rtosSetup function void rtosSetup() { pinMode(BLUE_LED, OUTPUT); myTask.begin(functionTask, Task_numPriorities - 1); // Solution 3: with Timer, works fine myTimer.begin(functionTask, 333); myTimer.start(); } |
My recommendation is to go for the third solution, where the function of the task functionTask() is explicitly called by a timer or a clock.
|