'Setting bits on Arduino freeRTOS
I have been studying freeRTOS on Arduino, and I made some code, as it follows So I got this Arduino RTOS code
#include <Arduino_FreeRTOS.h>
#include "event_groups.h"
#define red 6
#define Yellow 7
#define blue 8
#define TASK1_BIT (1UL<<0UL) //Unsigned long bit0 set to 1
#define TASK2_BIT (1UL<<1U)
EventGroupHandle_t xEventGroup;
void setup()
{
Serial.begin(9600);
pinMode(red,OUTPUT);
pinMode(blue,OUTPUT);
xEventGroup = xEventGroupCreate();
xTaskCreate(EventBitSettingTask,"Bit Setter",100,NULL,1,NULL);
xTaskCreate(EventBitReadingTask,"Bit Reader",100,NULL,1,NULL);
}
void EventBitSettingTask(void *pvParameters)
{
const TickType_t xDelay500ms = pdMS_TO_TICKS(500);
while(1)
{
xEventGroupSetBits(xEventGroup,TASK1_BIT); //Event,bit
vTaskDelay(xDelay500ms);
xEventGroupSetBits(xEventGroup,TASK2_BIT);
}
}
void EventBitReadingTask(void *pvParameters)
{
const EventBits_t xBitsToWaitFor = (TASK1_BIT | TASK2_BIT);
EventBits_t xEventGroupValue;
while(1)
{
xEventGroupValue = xEventGroupWaitBits(xEventGroup,xBitsToWaitFor,pdTRUE,pdTRUE,portMAX_DELAY);//EventGroup,receive, clear on exit, all bits?,wait
if(xEventGroupValue & TASK1_BIT != 0)
{
digitalWrite(red,digitalRead(red)^1);
}
if(xEventGroupValue & TASK2_BIT != 0)
{
digitalWrite(blue,digitalRead(blue)^1);
}
}
}
void loop() {
}
While playing with it, I realized if I set TASK1_BIT (1UL<<0UL)
to TASK1_BIT (0UL<<0UL)
, none of the leds will blink, but if I set TASK2_BIT (1UL<<1UL)
to TASK2_BIT (0UL<<1UL)
, just the red led will blink.
Apparently, the event of the blue led is dependent from the event of the red led, but why???
Solution 1:[1]
According to the FreeRTOS documentation, xEventGroupWaitBits()
is used to read the value of an event group and optionally wait in the blocked state for one or more event bits in the event group to become set.
The parameter xBitsToWaitFor
specifies which event bits in the event group will be tested. If the parameter xWaitForAllBits
is set to pdTRUE, bitwise AND will be used in the test. Setting xTicksToWait
to portMAX_DELAY will cause the task to wait without timing out. That means the task will leave a blocked state only when unblock condition is met.
When TASK1_BIT and TASK2_BIT are set to 0001 and 0010 respectively (in binary), the event group will leave the blocked state only when all the bits in the event group are equal to xWaitForAllBits
, in this case 0011. That will happen after two calls to xEventGroupSetBits()
.
After the event group leaves the blocked state, the value of each bit in the group will be compared to bit's default value, and if the particular bit was set, the led will blink. So by default, both leds should blink intermittently.
If you change the value of TASK1_BIT to 0 (by 0UL<<0UL), than the value of xBitsToWaitFor
will be 0010. The result of xEventGroupValue & TASK1_BIT
(0010 & 0000) will be 0 so the red led won't blink. On the other hand, the result of xEventGroupValue & TASK2_BIT
(0010 & 0010) will be != 0 so the blue led should blink.
Vice versa, if you set the value of TASK2_BIT to 0 (by 0UL<<1UL), than the value of xBitsToWaitFor
will be 0001. xEventGroupValue & TASK1_BIT
(0001 & 0001) will return 1 and the red led will blink. xEventGroupValue & TASK2_BIT
(0001 & 0000) will return 0 so the blue led shouldn't blink.
A detailed explanation of how these API-s work can be found at https://freertos.org.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |