Home > Back-end >  Arduino ESP32 FreeRTOS - How to declare empty byte array in task
Arduino ESP32 FreeRTOS - How to declare empty byte array in task

Time:03-09

I have the following FreeRTOS function:

void UARTSendCommand(void *pvParameters)
{
  (void) pvParameters;
  uint8_t receive[];  //***** NEED TO DO A EMPTY ARRAY 
  for (;;) 
    {
      xSemaphoreTake(xCountingSemaphore, portMAX_DELAY);
      xQueueReceive(queue, &receive, 0);
      if(receive)
      {
        Serial.println("UART Send command received");
        uart_write_bytes(UARTNUM, (const char*) receive, sizeof(receive));
      }
      xSemaphoreGive(xCountingSemaphore);
      vTaskDelay(1);
  }
}

The Queue is declared as:

 UARTSendQueue = xQueueCreate(10, sizeof(char));

And when I send to queue I do this:

byte message[] = {0x5A, 0xA5, 0x05, 0x82, 0x20, 0x00, (gaugeImage >> 8) & 0xFF, gaugeImage & 0xFF };
      xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); 
      xQueueSend(queue, &message, 0);
      xSemaphoreGive(xCountingSemaphore);

What I need is to get in my Task function the parameter sent in the queue, but I don't get anything.

Any clue?

CodePudding user response:

Queues are meant for sending/receiving one item at a time. You may want to check out the Stream Buffers, if you want to send/receive multiple items.

I'm going to assume that you want to queue complete messages, not single bytes and that the length of messages is 8, as per your code.

First, lets update the queue creation code to allocate space for messages, instead of bytes:

#define MAX_MESSAGES 10
#define MESSAGE_LENGTH 8
#define MESSAGE_SIZE (MESSAGE_LENGTH * sizeof(char))

UARTSendQueue = xQueueCreate(MAX_MESSAGES, MESSAGE_SIZE);

You seem to be using a semaphore to guard the queue access, but this is not necessary. To send the data, simply do:

xQueueSend(UARTSendQueue, message, 0);

On the receiving end, you need to specify the size of the array. Empty array does not make any sense here. You should also check the return type of xQueueReceive() to see if the data has been received:

uint8_t message[MESSAGE_LENGTH];
for (;;) {
    BaseType_t received = xQueueReceive(UARTSendQueue, message, 0);
    if (received) {
        ...

Note that I have removed & from message, as message is an array and it decays to pointer automatically.


Edit

In case of variable message lengh and where there are multiple senders, the simplest approach is to allocate the message buffer dynamically and to queue the pointer to allocated memory.

To create a queue:

#define MAX_MESSAGES 10
#define MESSAGE_SIZE sizeof(char*)

UARTSendQueue = xQueueCreate(MAX_MESSAGES, MESSAGE_SIZE);

To send a message:

uint8_t *message = (uint8_t *)pvPortMalloc(messageSize)
// Populate the message with the data here.

// Using portMAX_DELAY here to avoid memory leak.
// If message must be dropped, free the memory.
xQueueSend(UARTSendQueue, &message, portMAX_DELAY);

To receive the message:

uint8_t* message;
for (;;) {
    BaseType_t received = xQueueReceive(UARTSendQueue, &message, 0);
    if (received) {
        // Process the message
        // Free the memory
        vPortFree(message);
    }
}
  • Related