nicholasd wrote on Tuesday, April 17, 2018:
I’ve been experiencing difficulties in passing arrays via message queues using FreeRTOS. I am using Freertos v9.0, and my target device is the STM32L053 MCU (Cortex-M0+).
I have two threads:
- vKeypad() scans a keypad and sends a queue to vRadio that contains the corresponding keypad message. This thread runs periodically every ~100ms.
- vRadio() waits to receive queue contents, and then transmits the received message using a packet radio.
My application previously used the queue to pass a pointer to a 4-byte array to vRadio. This worked fine and data could be written by vKeypad() and read by vRadio() correctly without aparent issue. Recently my requirements changed, and I now need to use a 5-byte array instead of a 4-byte array, and the queue now seems to only pass the first four bytes properly, but the 5th byte is always 0 no matter what I do.
In my code below, I write a value of 55 to queueTX[4], the 5th element of the array whose pointer will be passed to the consumer thread vRadio. So I send queueTX= {11, 22, 33, 44, 55} to the array in vKeypad, and when vRadio receives the queue, queueRX contains {11, 22, 33, 44, 0}.
I’ve posted simplified pieces relevant source code below:
I initialize the queue as follows:
xRadioMessageQueue = xQueueCreate(1, sizeof(uint8_t *));
vKeypad thread (queue producer):
void vPortExpanderTask(void const * argument) {
uint16_t buttonState = 0x0000;
uint8_t queueTX[5] = {};
while(1) {
buttonState = readPortExpander(&hi2c1, PORT_EXP_ADDRESS);
// If a button has been pressed
if (buttonState) {
// Mock payload...
queueTX[0] = 11;
queueTX[1] = 22;
queueTX[2] = 33;
queueTX[3] = 44;
queueTX[4] = 55;
// Push data to xRadioMessageQueue
if ( xQueueSendToBack(xRadioMessageQueue, &queueTX, 10) != pdPASS ) {
// Queue full
} else {
// Queue write successful
}
}
vTaskDelay(100);
}
}
vRadio thread (queue consumer):
void vRadio(void const * argument) {
uint8_t queueRX[5] = {}; // Data received by xRadioMessageQueue queue
uint8_t destAddr = 1;
while(1) {
if ( xQueueReceive(xRadioMessageQueue, &queueRX, portMAX_DELAY) == pdPASS ) {
// Data has been successfully received by the queue
// Transmit the message
radioSendTo(&g_radio, (uint8_t *) queueRX, sizeof(queueRX), dest_addr);
}
vTaskDelay(250);
}
}
I would prefer to keep passing the array by reference, but if this implementation is flawed or anyone has suggestions on how to fix this, I would VERY much appreciate it!
Thanks.