|
NOTE:This is a read only archive of threads posted to the FreeRTOS support forum. Use these archive pages to search previous posts. New forum support threads can be started at the FreeRTOS forums.
FreeRTOS Support Archive
The FreeRTOS support forum can be used for active support both from Amazon Web Services and the community. In return for using our software for free, we request you play fair and do your bit to help others! Sign up for an account and receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum. Use these archive pages to search previous posts. New forum support threads can be started at the FreeRTOS forums.
[FreeRTOS Home]
[Live FreeRTOS Forum]
[FAQ]
[Archive Top]
[August 2016 Threads]
xQueueReceive Halts Entire SystemPosted by gstenos on August 17, 2016 I am having issues using the xQueueReceive function, I can not get the function to work properly and it also causes my whole system to halt. The version of FreeRTOS that I am using with my hardware is v7.3
I stepped through the debugger and identified the line of code that the system “halts” at, however, xQueueGenericReceive iterates through multiples times before the issue occurs.
The issue has occured on the 3rd and 4th iteration of when the function vListInsert. The code hangs up on line 165 in list.c which is given below:
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
The entire for loop is:
~~~
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
{
/* There is nothing to do here, we are just iterating to the
wanted insertion position. */
}
~~~
This is how I go about setting up my queue, how I send and how I receive.
~~~
typedef struct
{
char ucMessageID;
char ucData[ 20 ];
} AMessage;
xQueueHandle xQueue;
Setup_Function()
{
xQueue = xQueueCreate( 10, sizeof( AMessage *) );
}
Task_A()
{
AMessage *pxMessage;
memset(pxMessage->ucData, 0x00, sizeof(pxMessage->ucData));
for(;;)
{
pxMessage->ucMessageID = 0xDD;
pxMessage->ucData[0] = 'T';
pxMessage->ucData[1] = 'E';
pxMessage->ucData[2] = 'S';
pxMessage->ucData[3] = 'T';
pxMessage->ucData[4] = 'S';
xQueueSend( xQueue, ( void * ) pxMessage, ( portTickType ) 0 );
//rest of task code
}
}//end Task_A
Task_B()
{
AMessage *pxRxedMessage;
for(;;)
{
if( xQueueReceive( xQueue, pxRxedMessage, ( portTickType ) 10 ) )
{
// pcRxedMessage now points to the struct AMessage variable posted
// by vATask.
printf("Received: %c%c%c%c%cn", pxRxedMessage->ucData[0], pxRxedMessage->ucData[1], pxRxedMessage->ucData[2], pxRxedMessage->ucData[3], pxRxedMessage->ucData[4]);
}
}
}//end Task_B
~~~
I have verified that I am able to send something into the queue with the following print statement;
printf(“Number of messages in queue: %lun”, uxQueueMessagesWaiting(xQueue));
Then when I was trying to receive in another task to make sure all the data was correct, I started to have the issue that I outlined above. Nothing else on the system will execute once the line of code with xQueueReceive hits.
I’ve tried passing in just a struct AMessage as opposed to a pointer of struct AMessage, however the same issue occured where I verifed that messages were being sent to the queue but when xQueueReceive was commented out, the same issues occur.
xQueueReceive Halts Entire SystemPosted by rtel on August 17, 2016 Here –
~~~
typedef struct
{
char ucMessageID;
char ucData[ 20 ];
} AMessage;
~~~
you are declaring a structure that will, depending on structure packing, be at least 21 bytes big. There here –
~~~
xQueue = xQueueCreate( 10, sizeof( AMessage *) );
~~~
you are creating a queue that can hold ten pointers, so you cannot post an AMessage structure to the queue without corrupting a lot of RAM (as that would cause 21 bytes to be stored in a space that was only 4 bytes long). You don’t say which architecture you are using, but it is likely each pointer will be four bytes.
Next –
~~~
AMessage *pxMessage;
~~~
You are declaring a pointer to an AMessage structure, but leaving the pointer uninitialised, before:
~~~
memset(pxMessage->ucData, 0x00, sizeof(pxMessage->ucData));
~~~
dereferencing the uninitialised pointer and writing 20 zeros to unknown memory somewhere (I’m surprised this does not crash immediately as it is luck if the 20 bytes go into writeable memory).
Unfortunately I think there is quite a bit wrong with your code :o(
xQueueReceive Halts Entire SystemPosted by gstenos on August 17, 2016 Yes you’re totally right about the pointers being uninitialised, no idea how that escaped me. I didn’t understand size correctly, since I was passing in a pointer to AMessage I thought I would need sizeof(AMessage*) instead of sizeof(AMessage). I am still having the exact same issues though even after I initialize my pointers correctly and make certain the queue size gets set correctly.
I now have 2 extra variables in my code:
AMessage tempTXMessage;
AMessage tempRXMessage;
xQueue = xQueueCreate( 10, sizeof( AMessage ) );
Verified through printing that sizeof(AMessage) returns 21, which is the expected value.
Task_A()
{
AMessage *pxMessage = &tempTXMessage;
memset(pxMessage->ucData, 0x00, sizeof(pxMessage->ucData));
pxMessage->ucMessageID = 0x00;
for(;;)
{
pxMessage->ucMessageID = 0xDD;
pxMessage->ucData[0] = 'T';
pxMessage->ucData[1] = 'E';
pxMessage->ucData[2] = 'S';
pxMessage->ucData[3] = 'T';
pxMessage->ucData[4] = 'S';
xQueueSend( xQueue, ( void * ) pxMessage, ( portTickType ) 0 );
//rest of task code
}
}//end Task_A
Task_B()
{
AMessage *pxRxedMessage = &tempRXMessage;
memset(pxRxedMessage->ucData, 0x00, sizeof(pxRxedMessage->ucData));
pxRxedMessage->ucMessageID = 0x00;
for(;;)
{
if( xQueueReceive( xQueue, pxRxedMessage, ( portTickType ) 10 ) )
{
// pcRxedMessage now points to the struct AMessage variable posted
// by vATask.
printf("Received: %c%c%c%c%cn", pxRxedMessage->ucData[0], pxRxedMessage->ucData[1], pxRxedMessage->ucData[2], pxRxedMessage->ucData[3], pxRxedMessage->ucData[4]);
}
}
}//end Task_B
I’ve also tried sending and receiving the way that is outlined on FreeRTOS’s page regarding QueueReceive, http://www.freertos.org/a00118.html
The only difference that I can see between the implimentations is that I typedef my struct.
xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
if( xQueueReceive( xQueue, &pxRxedMessage, ( portTickType ) 10 ) )
Once it hits the if QueueReceive line it does not execute anything afterwards. I made sure to set the Queue size to that of the struct’s size to make certain I had enough space for all my messages.
xQueueReceive Halts Entire SystemPosted by rtel on August 18, 2016 I think this should work fine now – in fact I just tried it and found it
functioned as expected.
Some notes:
1) The send task is using a block time of 0, and the receive task is
using a block time of 10. That means you will have to give the receive
task a higher priority than the send task, so the receive task preempts
the send task each time the send task places an item in the queue
otherwise the queue will fill and the send task will keep spinning
around trying to post more. If you have the priorities in this way then
there will never be more than one item in the queue at any one time. To
add better flow control use a block time on both the send and the
receive ends.
2) I don’t know what else your code is doing – so if there is a problem
elsewhere I won’t see it.
3) As normal make sure you have stack overflow detection on and
configASSERT() defined during the development phase.
(http://www.freertos.org/FAQHelp.html)
xQueueReceive Halts Entire SystemPosted by gstenos on August 18, 2016 Thank you for running my code yourself to double check if it was correct.
- I had send executing in a task with a higher priority, but a timer of 1000ms. The task that receives has a higher priority but a timer of 10ms, so the task executes more frequently than the task that sends data to the queue.
- I’m going to go through and disable functionality as well as change where I send and receive to see where my issue is being caused.
3.Stack overflow detection I have set to 2, as for configASSERT this is how my FreeRTOSConfig.h file looks currently.
//#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ) __asm volatile( “NOP” ); }
(#)define configASSERT( x )
As of now memory is not an issue, would it be best to uncomment the first line and comment out #define configASSERT(x)?
xQueueReceive Halts Entire SystemPosted by edwards3 on August 18, 2016 I think the answer is in the preceding post
3) As normal make sure you have stack overflow detection on and
configASSERT() defined
xQueueReceive Halts Entire SystemPosted by gstenos on August 18, 2016 Turned out to be a simple fix gentleman, I changed where I receive in my task. Now I receive from the queue before taskENTER_CRITICAL() is called in that specific task. Now nothing no longer halts and I successfully receive the message that I am passing.
xQueueReceive Halts Entire SystemPosted by rtel on August 18, 2016 It doesn’t hold in all cases, but as a general rule of thumb, don’t call
API functions from inside a critical section or with the scheduler
suspended. The main reason being that a task might not be able to enter
the Blocked state if it tries if the API was called from inside one of
these two types of critical region (actually depends on the port being
used).
xQueueReceive Halts Entire SystemPosted by gstenos on August 18, 2016 Thank you I’ll be sure to avoid doing so in the future. I try my best from using taskENTERCRITICAL(), it is the only task that makes the function call and its respective, taskEXITCRITICAL().
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|
|