Hi,
I
m running freeRTOS on AVR mega 2560. I have two tasks A and B and also global data structure let
s name it G:
A – periodic (50 Hz) and responsible for reading data form sensor through I2C and performing some algorithm. It uses configuration stored in G.
void control
task(void * pvParameters)
{
TickTypet xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
while (1)
{
vTaskDelayUntil(&xLastWakeTime, (CONTROL
PERIODMS / portTICK
RATEMS));
// Read sensor
// Calibrate readings using data stored in G
// Perform algo using data stored in G
}
}
B – is responsible for communication through serial port with a PC application. Reception of each byte is done in the ISR. After receiving complete packet it`s processed in this task. Any other requests form PC between processing and trasmitting response are rejected. Some requests are read/write operations on struct G. Accessing G can occur anytime.
void serial
linktask(void * pvParameters)
{
while(1)
{
if(ready
toprocess == 1)
{
ready
toprocess = 0;
// Read form / write to data in G structure
// Prepare response
// Transmitt response (handeled in tx ISR)
}
}
}
Since these two tasks use global struct G it needs to be protected by a semaphore, mutex or copied into queue. I do not know which one should be used here.
Semaphore or mutex uses block time – how many ticks should wait for access. In the task A I do not want to wait for the semaphore or mutex to be obtained. It should be executed without any delay. Because it could happen that after giving the sem/mutex by task A task B takes this sem/mutex just before task A. Context switch is done and task A leaves empty handed.
if(pdTRUE == xSemaphoreTake(sem, 0)) <– oops task B as the sem/mutex
{
// Read sensor
// Calibrate readings using data stored in G
// Perform algo
xSemaphoreGive(sem);
}
Now the only solution that is working is to combine these two tasks into one like so:
void control
andserial
task(void * pvParameters)
{
TickTypet xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
while (1)
{
vTaskDelayUntil(&xLastWakeTime, (CONTROL
PERIODMS / portTICK
RATEMS));
// Read sensor
// Calibrate readings using data stored in G
// Perform algo using data stored in G
// Read form / write to data in G structure
// Prepare response
// Transmitt response (handeled in tx ISR)
}
}
But this limits serial throughput heavily. The other way I think is to use queues somehow. Can anyone help me how to solve the problem of sharing the data between tasks A and B without delaying execution of task A ?
Sorry for my english 🙂