#arduino #embedded #multitasking #freertos
#arduino #встроенный #многозадачность #фриртос
Вопрос:
Когда я пытаюсь отправить переменную из задачи в другую задачу, я ничего не могу получить с помощью xQueueReceive. Я использую UART и Arduino Mega. Я отправлю символ в Arduino, затем Arduino отправит этот символ на другое устройство. Но я не могу получить никакого результата. Вот мой код:
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#include <queue.h>
SemaphoreHandle_t xSerialSemaphore;
QueueHandle_t queue;
void TaskWrite( void *pvParameters );
void TaskRead( void *pvParameters );
void setup() {
Serial.begin(9600);
if ( xSerialSemaphore == NULL )
{
xSerialSemaphore = xSemaphoreCreateMutex();
if ( ( xSerialSemaphore ) != NULL )
xSemaphoreGive( ( xSerialSemaphore ) );
}
queue = xQueueCreate(15, sizeof(int));
if (queue == NULL) {
Serial.println("Queue can not be created");
}
// Now set up two Tasks to run independently.
xTaskCreate
TaskDigitalRead
, "Read"
, 256
, NULL
, 2
, NULL );
xTaskCreate(
TaskWrite
, "Write"
, 256
, NULL
, 1
, NULL );
}
void loop()
{
// Empty. Things are done in Tasks.
}
void TaskRead( void *pvParameters __attribute__((unused)) )
{
int c = 0;
for (;;)
{
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
xQueueReceive(queue, amp;c, 1000);
Serial.println(c);
xSemaphoreGive( xSerialSemaphore );
}
vTaskDelay(1);
}
}
void TaskWrite( void *pvParameters __attribute__((unused)) )
{
for (;;)
{
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
if(Serial.available()>0)
{
int c = Serial.read();
Serial.print("I received ");
Serial.println(c);
xQueueSend(queue, (void *)amp;c, 1000);
}
xSemaphoreGive( xSerialSemaphore );
}
vTaskDelay(1);
}
}
Если я включу строку xQueueReceive, я ничего не увижу на последовательном мониторе.
Комментарии:
1. Вам не нужен семафор. Просто заполните (потокобезопасную) очередь в одной задаче / irq и прочитайте ее из другой. Читайте также документы: freertos.org/Embedded-RTOS-Queues.html
Ответ №1:
Похоже, что может возникнуть условие прерывания гонки, если TaskRead сначала принимает семафор, пока очередь еще пуста. Почему бы просто не заблокировать TaskRead в xQueueReceive? Какова вообще цель семафора? Если вам действительно нужно защитить серийный номер самостоятельно, лучше используйте мьютекс для доступа к Serial.