In this example, Queue messages are used as communication method between tasks. The first task (Task_Selector
) used to transfer multiple data of each pin connected to LEDs every 2 seconds, and the second task (Task_Control
) uses this info to change the LED state reading each message of Task_Selector
every 200ms. When Task_Selector
executes again the LED status will change.
code example:
#include "bsp.h"
#include <math.h>
#define NUMBER_OF_LEDS 8 /* Indicate the number of LEDs */
#define NONE_MESSAGES 0 /* Indicate that No messages available */
#define RESET_VALUE 0 /* Default value to Restore a Variable */
static void Task_LED_Selector( void *parameters ); /* Task to select LED to be control */
static void Task_LED_Control( void *parameters ); /* Task to control LED status */
QueueHandle_t QueueLEDstatus;
int main( void )
{
HAL_Init( );
/*enable RTT and system view*/
SEGGER_SYSVIEW_Conf( );
SEGGER_SYSVIEW_Start( );
QueueLEDstatus = xQueueCreate( 8, sizeof(uint16_t) ); /* Create the Queue to store a data of 16 bits */
xTaskCreate( Task_LED_Selector, "Task_Selector", 128u, NULL, 1u, NULL ); /* Register a Task */
xTaskCreate( Task_LED_Control, "Task_Control", 128u, NULL, 1u, NULL ); /* Register a Task */
vTaskStartScheduler( ); /* initilize the kernel */
return 0u;
}
static void Task_LED_Selector( void *parameters )
{
UNUSED( parameters );
uint16_t Led_Pin[NUMBER_OF_LEDS] = { GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7 };
static uint16_t i = 0; /* Iter Value to send different messages */
for( ;; )
{
while( uxQueueSpacesAvailable( QueueLEDstatus ) > NONE_MESSAGES ) /* Check how many spaces the Queue has */
{
xQueueSend( QueueLEDstatus, &Led_Pin[i], 0 ); /* Send the data to Queue */
i++; /* Increment to select another data from Array */
}
i = RESET_VALUE; /* If Queue has no space, Reset the Value */
vTaskDelay(2000 / portTICK_PERIOD_MS); /* Periodicity of Task */
}
}
static void Task_LED_Control( void *parameters )
{
UNUSED( parameters );
uint16_t dataRead; /* Variable to store data of Queue */
for( ;; )
{
/* Enter to a loop to Read elements until Queue Buffer is zero */
while ( uxQueueMessagesWaiting( QueueLEDstatus ) > NONE_MESSAGES )
{
xQueueReceive( QueueLEDstatus, &dataRead, 0 ); /* Read the data of the Queue */
HAL_GPIO_TogglePin( GPIOC, dataRead ); /* Change the LED Status */
uint32_t res = log2(dataRead); /* Just convert message binary to Dec to be printed */
SEGGER_SYSVIEW_PrintfHost( "LED %d", res ); /* Print on Terminal the message received */
vTaskDelay(200 / portTICK_PERIOD_MS); /* Wait 200ms to read other msg */
}
vTaskDelay(200 / portTICK_PERIOD_MS); /* Periodicity of Task */
}
}
uxQueueMessagesWaiting()
Returns the number of messages to read, in the example used in a while loop to read and process all the messages until the queue has no more messages to read.SystemView output:
The terminal will show that task Task_LED_Control
prints the numbers of the LEDs received by the queue buffer, when the counter is restarted the LED state changes.
TimeLine:
Task Task_LED_Selector executes first and sends all the messages on Queue buffer, next the task Task_LED_Control executes and reads just a message from the buffer and waits 200ms for the next execution. |
|
After 200ms again Task_LED_Control executes and processes the next message. |
|
Finally, after 2 seconds, the first task Task_LED_Selector executes again sending all parameters, when finished, the task Task_LED_Control executes and now the LED state will change. |