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

Issue trying to queue message outside F-RTOS

Posted by Alex Lennon on July 14, 2013
Hi,

I am seeing a problem when I try to queue a message onto a FreeRTOS queue, which I suspect this is because I am going about it the wrong way.


I am using FreeRTOS 7.4.2 and the MSVC-MinGW port which I am using within Visual Studio 2010

(This is because for this project I want to simulate numbers of nodes running, each of which will be a separate instance of a FreeRTOS based application. Once I have written and validated my code I will then be porting to the real hardware)

Currently I am bringing up a single instance of FreeRTOS with a very basic comms. handler thread which dequeues a message and deals with it:


static void prvCommsTask( void *pvParameters )
{
serialPacket_t packet;

while(1)
{
if(xQueueReceive(_rxQueue, &packet, portMAX_DELAY))
{
// Loopback
if(_cb)
_cb(_sender, packet.pData, packet.length);

free(packet.pData);
}
}
}


I am queueing that message from a thread which is called from outside of the FreeRTOS sandbox though.
(the critical section is something I added to try to deal with the problem, but it doesn't help)


..
taskENTER_CRITICAL();

ret = xQueueSend(_rxQueue, (const void *)&packet, 500);

taskEXIT_CRITICAL();
}


When I run up my test, sending a packet of data into FreeRTOS I get an exception in list.c, uListRemove() on the following line


/* The list item knows which list it is in. Obtain the list from the list
item. */
pxList = ( xList * ) pxItemToRemove->pvContainer;

/* Make sure the index is left pointing to a valid item. */
if( pxList->pxIndex == pxItemToRemove )


This is because pvContainer is NULL, which would seem to indicate the list item is somehow unhooked from its list. It makes me think there is perhaps a race.

In the real device the bytes would come in on a UART, trigger the interrupt handler, and I presume all would be well.

Any feedback on the above would be much appreciated, or any thoughts on a better implementation to get bytes into FreeRTOS from a hosted environment.

Many thanks,

Alex Lennon
Dynamic Devices

RE: Issue trying to queue message outside F-RTOS

Posted by Richard on July 15, 2013
I'm not exactly sure what you mean by sending to a FreeRTOS thread outside of FreeRTOS. Do you have some kind of shared memory to access the queue structure?

Anyway, first you must not send to a queue from inside a critical section. Your queue send call is asking for a block time of 500 ticks. If the function attempts to block when you are in a critical section the behaviour will depend on the port, but is extremely unlikely to be desirable.

This then also brings up the question of what is expected to happen if code that is not bring run as part of your FreeRTOS application makes a call that results in the scheduler trying to pre-empt something which it does not even know is running. Hence my confusion stated in the first paragraph.

Regards.

RE: Issue trying to queue message outside F-RTOS

Posted by Alex Lennon on July 15, 2013
Hi Richard,

Thanks for the response.

"I'm not exactly sure what you mean by sending to a FreeRTOS thread outside of FreeRTOS."

Outside FreeRTOS task/resouce management, i.e. from a Win32 thread of excecution. FreeRTOS itself is wrapped up in a DLL and running in a separate thread (threads) of execution.

"Anyway, first you must not send to a queue from inside a critical section."

OK - thanks for the advice. That was added for test. The behaviour is the same without the critical section.

"Your queue send call is asking for a block time of 500 ticks."

Yes, again for test. This is blocking the Win32 thread of execution from the hosted environment (the equivalent of a timeout on a UART write), not blocking the FreeRTOS scheduler.

Best,

Alex

RE: Issue trying to queue message outside F-RTOS

Posted by Alex Lennon on July 15, 2013
Hi,

I've taken a step back to make sure I understand what I'm doing with queuing and the WIN32-MSVC demo.

I downloaded FreeRTOSV7.4.2 again and extracted. then loaded the WIN32 solution into VS2010.

I get some compile errors relating to the location of the trace source. To resolve these I need to change an include path:

..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\Include

to

..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\Include

Then the same for the paths to the various trcXXX.c files. (Perhaps the trace source has moved to a new "Source" folder at some point?

This gets the demo compiling and running OK as far as I can see.

Next I created a queue and added in two simple tasks. A sender and a receiver


pxMyQueue = xQueueCreate( 10, 8);

xTaskCreate( prvTxTask, ( signed char * ) "Tx", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
xTaskCreate( prvRxTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
...
/* Start the scheduler itself. */
vTaskStartScheduler();



static void prvTxTask( void *pvParameters )
{
byte data[8];

while(1)
{
OutputDebugString("Send data\n");
xQueueSend(pxMyQueue, data, 0);

//Sleep(1000);
vTaskDelay(1000);
}
}

static void prvRxTask( void *pvParameters )
{
byte data[8];

while(1)
{
if(xQueueReceive(pxMyQueue, data, portMAX_DELAY))
{
OutputDebugString("Got data\n");
}
}
}


With the Sleep(1000) call, which I thought would be OK to use as it is used in prvTestTask() I get an assertion which is raised in timerdemo.c


/* Both timers should now have expired once. The auto reload timer will
still be active, but the one shot timer should now have stopped. */
if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) )
{
xTestStatus = pdFAIL;
configASSERT( xTestStatus );
}


If I replace that Sleep() call with the vTaskDelay() then the xQueueSend() and and xQueueReceive() works as expected.

If I then add a call to a callback function into my xQueueReceive() function, and have that callback set to a function within the FreeRTOS main.c file all still works as expected and I can breakpoint on that callback.



static int _cdecl NodeCallback(void *sender, byte data[], int length);

static void prvCommsTask( void *pvParameters )
{
serialPacket_t packet;

while(1)
{
if(xQueueReceive(_rxQueue, &packet, portMAX_DELAY))
{
OutputDebugStringW(L"Rxing.\n");

// Loopback
if(_cb)
_cb(_sender, packet.pData, packet.length);

//free(packet.pData);
}
}
}
..
static int _cdecl NodeCallback(void *sender, byte data[], int length)
{
return 0;
}



However when I set that callback to a function that is in the process which is hosting the FreeRTOS DLL then I still get the callback, i.e. I can breakpoint in the external function but the queuing and receiving then seems to "stop". I've looked at ensuring the calling conventions for the function pointer and function itself are correct and I'm not sure what it can be. I am wondering if I'm corrupting the stack somehow with the call.

I appreciate we're now outside the scope of FreeRTOS and into the world of Win32 and DLL hosting so I shall just keep plugging away here :)

Thanks & Best Regards,

Alex

RE: Issue trying to queue message outside F-RTOS

Posted by Richard on July 15, 2013
“I get some compile errors relating to the location of the trace source.”


Yes - sorry about that. It is on the published known issues list and resulted from the trace source files moving in the directory structure without the project being updated.

“If I then add a call to a callback function into my xQueueReceive() function, and have that callback set to a function within the FreeRTOS main.c file all still works as expected and I can breakpoint on that callback.”


The callback is running in the context of the task. It is just like calling any function from the task.

“However when I set that callback to a function that is in the process which is hosting the FreeRTOS DLL then I still get the callback, i.e. I can breakpoint in the external function but the queuing and receiving then seems to "stop"”


I don't know enough about Windows programming, but presumably the function is now running outside of the context of the task. The manages the the task context and will no doubt get confused by the memory presented to it in the queue function being elsewhere. I've never tried this type of scheme, although FreeRTOS has been used on multi-processor systems (both running FreeRTOS on each core which is the simple scenario, and running just one version of FreeRTOS that runs tasks on multiple cores which is the complex scenario).

Regards.

RE: Issue trying to queue message outside F-RTOS

Posted by Alex Lennon on July 15, 2013

It's very, very strange.


while(1)
{
if(xQueueReceive(_rxQueue, &packet, portMAX_DELAY))
{
OutputDebugStringW(L"Rxing.\n");

// Loopback
if(_cb)
{
_cb();
}
}
}


The queueing task is as above. The callback is set to an empty function outside of the DLL, so it should just get called and return.

When the first message is received, if I breakpoint on the _cb line and then run I will never get another message. The vTaskDelay() in the sending task never seems to return.

However if I breakpoint on the _cb and *single step over the call*, then run, everything works fine (!!!) I can then take out the breakpoint, leave it running with no problem.

There is something very strange going on.

Regards,

Alex

RE: Issue trying to queue message outside F-RTOS

Posted by Alex Lennon on July 15, 2013

With some more debugging I'm starting to come back to the idea that this might be timing related.

I was looking at the situation when my xQueueSend() task "stops" - i.e. doesn't come back from vTaskDelay().

I can see the Win32 port simulated timer interrupt firing. It then tries to kick off a task switch with vTaskSwitchContext() but this does not happen as uxSchedulerSuspended is TRUE.

When I add a debug string output into void vTaskSuspendAll() and xTaskResumeAll() I no longer get the failure, which makes me think of races.

Will continue looking.

Alex




RE: Issue trying to queue message outside F-RTOS

Posted by Alex Lennon on July 15, 2013

Some more debugging and I can see where it is failing, although don't yet know why.

The xQueueReceive() in prvRxTask() is looping in vListInsert() for some reason. This is whilst scheduling is suspended, which of course is why scheduling stops...


.dll!vListInsert(xLIST * pxList=0x0fb16004, xLIST_ITEM * pxNewListItem=0x0fb1621c) Line 171 + 0x14 bytesC
dll!vTaskPlaceOnEventList(const xLIST * const pxEventList=0x0fb16004, unsigned long xTicksToWait=0x00000064) Line 1863 + 0x12 bytesC
.dll!xQueueGenericReceive(void * xQueue=0x0fb15fe0, void * const pvBuffer=0x07b7fdf8, unsigned long xTicksToWait=0x00000064, long xJustPeeking=0x00000000) Line 1142 + 0x10 bytesC
.dll!prvCommsTask(void * pvParameters=0x00000000) Line 137 + 0x14 bytesC


It's interesting as looking at the iterator next just points back to itself which is why it's looping


pxIterator = 0x0fb1621c {xItemValue=0x00000002 pxNext=0x0fb1621c pxPrevious=0x0fb1621c ...}
xItemValue = 0x00000002
pxNext = 0x0fb1621c {xItemValue=0x00000002 pxNext=0x0fb1621c pxPrevious=0x0fb1621c ...}
pxPrevious = 0x0fb1621c {xItemValue=0x00000002 pxNext=0x0fb1621c pxPrevious=0x0fb1621c ...}
pvOwner = 0x0fb16204
pvContainer = 0x0fb16004


I see the notes on "If you find your application is crashing here then likely causes are". The Win32 port thread stack size should be the default 1MB I believe. I don't seem any SYSCALL interrupt definitions in the configuration file, I haven't added anything that calls an API fn in a critical section, and the queues are only being used within the two tasks, so not before the scheduler starts.

Not sure what to make of it.


[ 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