embOS offers the ability to extend the context of a task by creating our own structures with the elements we want. This way, we can fill the structure elements in main function and use them within the task and all of this with a single function and with the function “OS_TASK_CREATE()
"
Now our Control Task Blocks has to be the structure data type as you can see below.
#include "bsp.h"
/* In this case I'm adding 3 more elements apart from the Task Control Block
but you can add any number of elements to extend the context */
typedef struct{
OS_TASK Task; // OS_TASK has to be the first element
char *Message; // String to print a message
OS_TIME Delay; // Delay value for each task
uint16_t Pin; // Pin number
}MY_APP_TASK;
static int HPStack[128], LPStack[128]; // Task stacks
static MY_APP_TASK HPTask, LPTask; // Task control blocks
void Task_Demo( void );
int main( void )
{
OS_Init(); // Initialize embOS (must be first)
HAL_Init();
OS_InitHW(); // Initialize Hardware for embOS
HPTask.Message = "TASK 1";
HPTask.Delay = 30;
HPTask.Pin = GPIO_PIN_0;
LPTask.Message = "TASK 2";
LPTask.Delay = 10;
LPTask.Pin = GPIO_PIN_2;
OS_TASK_CREATE(&HPTask.Task, "HP Task", 100, Task_Demo, HPStack);
OS_TASK_CREATE(&LPTask.Task, "LP Task", 50, Task_Demo, LPStack);
OS_Start(); // Start multitasking
return 0u;
}
void Task_Demo( void ){
MY_APP_TASK* pThis;
char *Message;
OS_TIME Delay;
uint16_t Pin;
pThis = (MY_APP_TASK*)OS_TASK_GetID();
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOC_CLK_ENABLE( );
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_2;
HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );
for( ;; ){
Message = pThis->Message;
Delay = pThis->Delay;
Pin = pThis->Pin;
SEGGER_SYSVIEW_PrintfHost( Message );
HAL_GPIO_TogglePin( GPIOC, Pin );
OS_TASK_Delay( Delay );
}
}
Now you know how to use the context of a task and how to extend it through a custom structure.
SYSTYEMVIEW
Build and flash the program and then run systemview.

Look at the timeline. You can see how every 10ms a task runs (TASK 2) and when the program reaches 30ms both tasks run. This means that the tasks are running according with their respective delays.

looking closer you can notice how the tasks are running according with their priorities.