FreeRTOS Simple Tasks – Passing Parameters

Keywords: Embedded systems, ARM, FreeRTOS, STM32F4, Tasks

Code Link: Tutorial Source Code Github – Keil

In the previous tutorial we explained how to create simple freeRTOS tasks. We created two tasks and used separate task function for each task – also no parameters were passed to task functions Figure-1.

Figure-1: FreeRTOS Task Link with respective Task Function

This tutorial is about making the previous tutorial code a bit more sophisticated. In this tutorial we will use a single task function to be used by multiple freeRTOS Tasks Figure-2.

Figure-2: FreeRTOS one Task function for multiple Tasks

Each task will inform “Task Function” which task is using the function code by passing information via void * pvParameters parameter of xTaskCreate(...) API. In our case Task-1 will pass 1 (numeric 1) and Task-2 will pass 2 (numeric 2) as an indication of which task is calling the task function code.

Procedure:

Following is the procedure to pass parameters to Task function.

  1. Declare/Define variables (of any data type) holding data to be passed to Task Function.
  2. Declare a pointer to these variables.
  3. Cast the pointer to (void *)
  4. Cast back to original datatype pointer in Task Function.

Let’s jump to programming above steps.

Steps:

1. Create two variables holding data to be passed to Task Function. In our case, as mentioned earlier, data is simple digits 1 and 2. Again its not mandatory that the data type be integer.

  const int task_1_Num = 1;
  const int task_2_Num = 2; 

2. As xTaskCreate (...,void *pvParameters,...) accepts a pointer to void, so we need either pointers to above variables or we can use an in place pointer during Task creation and cast it as well in Task API i.e.

  xTaskCreate (vTask, "T1", 150, (void *)&task_1_Num, 1, NULL);

  xTaskCreate (vTask, "T2", 150, (void *)&task_2_Num, 1, NULL);

The & sign return the pointer (address) of variables task_1_Num , task_2_Num. The (void *) cast the pointer type from the const int * (in this case) to void * as per the requirement of xTaskCreate(...) API.

3. In task function, Cast back to original data type pointer and use it. In our case as we casted from Pointer-to-integer to Pointer-to-void so we will cast it back to Pointer-to-integer as Pointer-to-void can’t be dereferenced.

  int *param = (int *)pvParams;

We are using this pointer to print the Task number via printf function. The task function is given bellow.

/*
 Task function to be used by both FreeRTOS Tasks.
*/
void vTask(void * pvParams) {

  volatile unsigned int i = 0;
  
  /*Casting back to original data type pointer*/
  int *param = (int *)pvParams;

  for (;;) {
    printf("Task-%d Running\n", *param );
    
    /*Dummy Delay - Lazy work */
    for (i =0; i < 50000; ++i);
  }
}

4. Compile source code, connect STM32F4-Discovery board to PC and enter debug mode. Open printf serial window via View -> Serial Windows -> Debug (printf) Viewer. Run the Program, You will see Task execution messages as shown in bellow Video.

Note: We have routed printf messages to ST-Link debugger via ARM-ITM. There is a dedicated tutorial on how to redirect printf messages to debugger. Link to the tutorial is given bellow.

For complete source code refer to Github link given at the start of this tutorial.

Click the full screen button for more clear view.

References:

[1] – FreeRTOS Official Website



164 thoughts on “FreeRTOS Simple Tasks – Passing Parameters”

Leave a Reply

Your email address will not be published. Required fields are marked *