4
votes

I'm having trouble sending multiple queues to a task in FreeRTOS.

I've tried creating a struct to hold them like this:

typedef struct
{
    xQueueHandle buttonQueue;
    xQueueHandle OLEDQueue;
} xQueues;

and then sending it to the task like this:

void vStartADCtasks( xQueueHandle xButtonQueuex, QueueHandle xOLEDQueue )
{
    xQueues xADCQueues = { xOLEDQueue, xButtonQueue };
    xTaskCreate( vGetAltitude, "Get Altitude", 240, (void *) &xADCQueues, 2, NULL );
}

and accessing it like this in the task:

static void vGetAltitude(void *pvParameters) {
    xQueues *xADCQueues = ( xQueues * ) pvParameters;
    xQueueHandle xOLEDQueue = xADCQueues->OLEDQueue;
    xQueueHandle xButtonQueue = xADCQueues->buttonQueue;

but that doesn't work. Any tips? I guess my more general question is how to pass around a queue between multiple .c files. ie. create it and one file, but be able to use it in a task in another file?

1

1 Answers

5
votes

You've got 3 bugs. First is that you've swapped the order of the queues when you try initializing xADCQueues. Second, you should pass xADCQueues as the 4th argument to xTaskCreate. Third, your xADCQueues struct is created on the stack, which means that after vStartADCtasks returns, that struct is destroyed and overwritten.

Replace your vStartADCtasks with this

xQueues xADCQueues;
void vStartADCtasks( xQueueHandle xOLEDQueue, xQueueHandle xButtonQueue )
{
    xADCQueues.buttonQueue = xButtonQueue;
    xADCQueues.OLEDQueue = xOLEDQueue;
    xTaskCreate( vGetAltitude, "Get Altitude", 240, (void *) &xADCQueues, 2, NULL );
}

or don't bother creating xADCQueues at all, but just make xButtonQueue and xOLEDQueue global variables. I don't see anything wrong with doing that for embedded systems... I know they teach you in school to avoid global variables, but in this case, it is a good idea to make the variables global and static since they are shared by tasks.