Message Queue Data

Hello: I’m trying to get a message queue functioning in a particular way but having a bit of trouble, so hoping that someone could provide some help. First, I need to send data to a UART using a single-point queue. So I have created that queue and it works with no issues. However, I have 2 structure types I need to get to the queue. The first has 12 different data members. The size of the struct is 41 bytes – call this “sType” Some of the messages I need to send to the UART are strings only, used to control the touchscreen. So I have defined another structure that contains just 2 data members, an int and an array of 40 chars. Also 41 chars. Call this “uType”. Since the queue task handler was created for “sType”: uint16t QUEUEITEM_SIZE = sizeof( *sType ); How can I possibly send an instance of the other data structure to the queue? In short, I need to send one of 2 types to the queue. Thank you for any help on this.

Message Queue Data

As in both cases you are sending quite a lot of date it might be best to send a pointer to the data, rather than the data itself. Then you have two options: 1) Have the first member of both structures identify the structure type. So when you receive a pointer from the queue you de-reference the first byte or word (depending) to see what the structure is (the first byte or word identifying the structure). Then when you know what the structure is you can cast the pointer to whichever structure it was determined to be. 2) Create the queue to hold structures that have two members. The first member identifies what the second member points to. So you receive the structure from the queue, check the first member to determine what the second member is pointing to, then cast the second member to whichever structure it was determined to be. Of course, when queuing pointers to structures, rather than queuing the structures themselves, you have to be careful that the sender does not access the structure again until the receiver has finished with it. That can be done by having the receiver return the structure to a pool of structures when it is finished with it, or have the sender dynamically allocate the structure and the receiver free the structure again (not always a good solution, but it depends on your scenario).

Message Queue Data

Hi, Thanks for the explanation. I tried both methods, and they both work. In the sending task I have 2 (test) assignments where I assign the structure “type”, format the appropriate string buffer and then use the function xQueueSendToBack to send the structure pointer. The sending task (for testing) is called at 1000ms. However: if I do not put “vTaskDelay(x)” between those 2 calls in the sending task, the queue handler always identifies the structure as the first one I sent. The delay can be 1 millisecond, and it works fine. Again – this occurs with either method you described.

Message Queue Data

Are you 100% sure you are not accidentally using, sending, or checking the same buffer (that is, the buffer being pointed to) twice? Also, only the buffer that contains the data should be pointed to – the structure that contains the pointer to the data should still be copied to the queue in the normal way.

Message Queue Data

Yes, I think everything is correct. From the sending task: vTaskDelayUntil( &xLastCheckTime, TESTSENDRATE ); ~~~ memzero( scrObj->str, 20 );
strType->type = iTOOL;
sprintf( scrObj->str, “%s”, “Here is data for #1r” ); xQueueSendToBack(screenUpdatesQueue, strType, portMAX_DELAY ); vTaskDelay(1); //need this here to work… memzero( uartObj->str, 43 );
sprintf( uartObj->str, “%s”, “Here is bigger data for #2r” ); strType->type = iUART; xQueueSendToBack(screenUpdatesQueue, strType, portMAX_DELAY ); ~~~ Then, from the queue handler: QueueHandlet taskQueue = (QueueHandlet) pvParameters; ~~~ if( xQueueReceive ( taskQueue, strType, portMAX_DELAY ) == pdPASS) { if( strType->type == iUART ) { uartObj = (uOBJ *) strType; printf(“UART TYPE: Handle = %i, str = %sn”, uartObj->handle, uartObj->str ); } else { scrObj = (sOBJ *) strType; printf(“NOT UART TYPE: Handle = %i, str = %sn”, scrObj->handle, scrObj->str );
} ~~~ Also, something strange. When I allocate memory for the strType pointer struct, I also cast it to one of the types so it’s pointing at something: strType = malloc(sizeof(sPTR)); strType->pType = (uOBJ*)uartObj; strType->type = iUART; In spite of this, on the first pass, both strings are junked out. What am I missing, that it works with the vTaskDelay() in between, and does not if it’s not there? In either case, with or without the delay, the first pass prints junk from the string buffer (although the type is correctly identified) Thanks again for your assistance.

Message Queue Data

It’s not clear to me what this code is doing. I have tried to annotate it with comments below: ~~~ /* Does scrObj->str point to a buffer, or is it an array? */ memzero( scrObj->str, 20 ); /* Setting the type of the object being pointed to to iTOOL, and writing text to the buffer pointed to by scrObj->str. */ strType->type = iTOOL;
sprintf( scrObj->str, “%s”, “Here is data for #1r” ); /* Writing the value of the strType pointer to the queue. So this will post the address held in the strType variable to the queue. Is strType pointing to scrObj at this point? */ xQueueSendToBack(screenUpdatesQueue, strType, portMAX_DELAY ); vTaskDelay(1); //need this here to work… /* Do the same for uartOjb. */ memzero( uartObj->str, 43 );
sprintf( uartObj->str, “%s”, “Here is bigger data for #2r” ); strType->type = iUART; /* strType has not been updated since the last call to xQueueSendToBack(), so it is still pointing to the same thing. So the receiving task will receive the same pointer value twice – so would expect to receive the same thing twice. What is strType pointing to? If the receiving task has an equal or lower priority I expect this to go wrong because what is being pointed to is overwritten by the sending task before the receiving task has accessed it (also explains why adding the vTaskDelay(1) fixes the issue, as that would allow the receiving task to run and process the first message before the sending task overwrites it). */ xQueueSendToBack(screenUpdatesQueue, strType, portMAX_DELAY ); ~~~