DEV HW: Freescale TWR-K60D100M (ARM Cortex M4)
I have a simple producer consumer set up:
Producer and Consumer task priorities are equal.
void vMsgProducerTask(taskparamt pvParameters)
printf("starting producer tasknr");
uint32t x = 0;
sprintf(message,"Message # %d",x);
printf("producing message %dnr",x);
CHECKERR(OSAMsgQPut(msgQ1handle,message) != kStatusOSASuccess);
void vMsgConsumerTask(taskparamt pvParameters)
printf("nrstarting consumer tasknr");
CHECKERR(OSAMsgQGet(msgQ1handle,message,OSAWAITFOREVER) != kStatusOSASuccess);
printf("consuming message: %snr",message);
OSAMsgQPut() maps to xQueueSendToBack()
OSAMsgQGet() maps to xQueueReceive()
So when this code is ran, the following happens:
1. Consumer task starts, blocks waiting for message. Queue adds consumer task to xTasksWaitingToReceive.
2. Producer task starts, creates message. uxMessagesWaiting increments. Producer task yields.
3. Consumer task resumes. Consumer task runs and blocks for new message.
4. Producer task resumes. Break before generating message. This time, the queue has added the producer task to the xTasksWaitingToReceive list.
In xTaskRemoveFromEventList(), the xEventListItem next and previous values are 0's and this causes a hard fault in uxListRemove().
I would think that the consumer task should be added to the waiting list for the message queue (as was done in the first iteration), but the producer task was added instead. And the producer task doesnt need to wait for the queue...
Any thoughts, suggestions, etc for this?
First a couple of comments:
I can't see anything in your code that shows the queue being created. Maybe you just left that out for brevity, but it would be interesting to see what the queue is being created to hold. The main reason for asking is that you are declaring a buffer on the stack of one task, then sending that buffer to the other task - but how is the message going through the queue? If it is copying the buffer into the queue then that should work, albeit perhaps in not the most efficient way. If on the other hand you are just queuing a pointer to the buffer then the consumer will end up with a pointer to memory that is declared on the stack of another task - that is not good - especially as the producer is able to overwrite the memory at any time.
How is printf() implemented? You are calling it from more than one task, which means it may need to be called from a critical section (vTaskSuspendAll()/xTaskResumeAll() for example). Also, make sure its implementation is not going to interfer with the execution of the task.
Where did the OSA_nnn functions come from? Are they from the Freescale KSDK? If so, I'm sure they will be fine, but if not, try calling the native API directly. That would at least allow me to see how the API was being used.
Yes. the OSA_nnn functions are from the freescale KSDK. I left the queue creation out for brevity. It doesn't return an error during creation.
I did create a version that does work. PFA my working source.
It seems to stem from the creation of the queue itself. Depending on what value I input for the size of the queue in xQueueCreate() it will fail. I was previously using OSA_MsgQCreate() which returned
return xQueueCreate(messagenumber, messagesize*sizeof(uint32t));
(I dont understand the need to multiply by the size of uint32t in the first place)
I modified it by removing the multiplication and renamed it to OSAMsgQCreate() (as you can see in the source file) and it works as expected.
Is there any more information you can give as to why some of the values I put in for uxItemSize are problematic and others aren't?
I'm afraid the fact that the messagesize parameter is being multipled by sizeof( uint32t ) makes me realise I don't know how the OSA_nnn version of the functions are intended to be used. Normally when creating a queue you would pass in the queue item size exactly as you would expect to get back when calling sizeof() on the data type being queued. In this case it looks like it is wanting the number of 32-bit values - which would suggest it could possibly also want 32-bit alignment - which may be the cause of your issue.
It looks like I can adjust the size of the message (by altering the message structure) and can get it to work just fine. But, if I create the queue with a size that is different than that of the message that will be posted to it, it will end up with some unexpected behaviors. Is that what you would expect? Even if the object you are posting is smaller than the defined size when you created it?
In FreeRTOs each space in the queue is the same size. For example, lets say each space in 10 bytes. If you then try to queue an 4 byte object, then 10 bytes will be copied into the queue - so you will get the 4 bytes you intended, plus the 6 following bytes. That should not be a problem when sending to a queue - but the opposite is not true. In the above example, when reading from the same queue, you must supply a buffer that is at least 10 bytes long, as 10 bytes will be copied out of the queue.