This is my first attempt at ESP IDF and messing with FREERTOS.
I am using an ESP32 DEVKIT, PlatformIO, and ESP IDF.
I am using ESP IDF build 4.4.0
I created 2 tasks, and one queue to share. The issue is that if the xQueueSend has a delay that is longer that the xQueueReceive, the queue loses data. Am i doing something wrong?
My understanding of the tasks are that they timeshare since the priority is set the same.
Even though the receive task cannot complete in its time slot (10ms), i thought that through context switching, the receive task would resume where it left off. In this case even seems as when it restore and reads from the queue it is missing one of the items in the queue, as if the queue got reinitialized
extern "C"
{
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "string.h"
}
#include <string>
static const char *TAG = "main";
struct message
{
std::string rx_buffer;
};
struct commander_parameters
{
QueueHandle_t xUdpQueue;
};
struct udp_server_parameters
{
QueueHandle_t xUdpQueue;
};
void udp_server_task(void *pvParameters);
void commander_task(void *pvParameters);
extern "C" void app_main()
{
BaseType_t xReturned;
QueueHandle_t xUdpQueue = xQueueCreate(20, sizeof(message));
udp_server_parameters udp_parm = {
.xUdpQueue = xUdpQueue,
};
commander_parameters commander_parm = {
.xUdpQueue = xUdpQueue,
};
xReturned = xTaskCreate(commander_task, "commander_task", 1024 * 16, &commander_parm, 11, NULL);
if (xReturned != pdPASS)
{
ESP_LOGE(TAG, "Failed to create Commander Task");
}
xReturned = xTaskCreate(udp_server_task, "udp_task", 1024 * 16, &udp_parm, 11, NULL);
if (xReturned != pdPASS)
{
ESP_LOGE(TAG, "Failed to create UDP Server Task");
}
vTaskStartScheduler();
}
void udp_server_task(void *pvParameters)
{
// ESP_LOGI(TAG, "UDP Server Task starting up...");
QueueHandle_t xUdpQueue;
char rx_buffer[128];
message udp_message;
int ret;
udp_server_parameters *pTaskParameters = (udp_server_parameters *)pvParameters;
if (NULL == pTaskParameters ||
NULL == pTaskParameters->xUdpQueue)
{
// ESP_LOGE(TAG, "UDP Task parameters were missing, exiting.");
vTaskDelete(NULL); // Delete self.
}
// ESP_LOGE(TAG, "UDP Task parameters were OK");
xUdpQueue = pTaskParameters->xUdpQueue;
// ESP_LOGE(TAG, "UDP OK");
while (true)
{
for (int x = 1; x < 10; x++)
{
sprintf(rx_buffer, "%i", x);
udp_message.rx_buffer = rx_buffer;
printf("Write queue:%s\n", udp_message.rx_buffer.c_str());
ret = xQueueSend(xUdpQueue, &udp_message, pdMS_TO_TICKS(0));
vTaskDelay(pdMS_TO_TICKS(500));
}
}
}
void commander_task(void *pvParameters)
{
// ESP_LOGD(TAG, "Commander Task starting...");
message commander_message;
QueueHandle_t xUdpQueue;
commander_parameters *pTaskParameters = (commander_parameters *)pvParameters;
if (NULL == pTaskParameters ||
NULL == pTaskParameters->xUdpQueue)
{
ESP_LOGE(TAG, "Task parameters were missing, exiting.");
vTaskDelete(NULL); // Delete self.
}
// ESP_LOGE(TAG, "Task parameters were OK.");
xUdpQueue = pTaskParameters->xUdpQueue;
// ESP_LOGE(TAG, "Got parameters");
while (true)
{
if (xQueueReceive(xUdpQueue, &commander_message, portMAX_DELAY))
{
printf("Recv Buffer:%s\n", commander_message.rx_buffer.c_str());
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
}
OUTPUT:
Write queue:4
Write queue:5
Recv Buffer:5
Write queue:6
Write queue:7
Recv Buffer:7
Write queue:8
Write queue:9
Recv Buffer:9
Write queue:1
Write queue:2
Recv Buffer:2
Write queue:3
Write queue:4
Recv Buffer:4
Write queue:5
Write queue:6
Recv Buffer:6
Write queue:7
Write queue:8
Recv Buffer:8
Write queue:9
Write queue:1
Recv Buffer:1