Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

xQueueReceive Halts Entire System

Posted 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%c\n", 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 System

Posted 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 System

Posted 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%c\n", 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 System

Posted 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 System

Posted by gstenos on August 18, 2016

Thank you for running my code yourself to double check if it was correct.

  1. 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.

  2. 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 System

Posted 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 System

Posted 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 System

Posted 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 System

Posted 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().


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists