PIC24 C30 queues work locally, not globally

cmauler wrote on Saturday, May 21, 2011:

Defining a queue in a task (ie local) behaves as expected*, but when the queue is defined globally then initialised in main (and checked the return code for success) the task is oblivious ie a length check has an erroneous return value and queue operations fail resulting in multitasking failure.

*like GenQTest.c operation to check a queues functionality with send and receive in the same task (but this has a passed in queue)

Download Community Contributed  port using LM19 temperature sensor and got a three task flashing LED working on my newish MPLAB V3.25 and noticed FreeRTOS was V5.4.2
Read about queues and tried a test and resulted in multitasking failure as another task just flashing a led with a delay, failed.
Pared back to get something to work which is defining the queue handle in a task, creating the queue, checking the return code, then sending and receiving and length check all function.
defining globally, creating and checking in main and using in task….fails
- debug stops at “for( pxIterator = ( xListItem * ) &( pxList->xListEnd );…”
-FAQ9.1"stack"=checked,  FAQ9.2"priority"=inherited working? tried variations, FAQ9.3"API"=not relevant 
- not caught in the enabled stackoverflow trap, that works when the stack is reduced
- not affected by doubling the stack till stack allocation fails and falls into the post scheduler trap
- no success with changing configUSE_PREEMPTION, INCLUDE_*,HEAP,configTICK….
- tried defining a global byte variable alongside, initialised alongside in main and was usable in the task, so confirming something can be used globally
- tried removing the global definition and it gives the expected compilation warnings so demonstrating the global definition is correctly typed for that instance of use
- tried passing in the queue handle (as per  GenQTest.c)
- tried Googling …and a few choice words

I guess my next step is a rewrite from scratch with the latest version! as it maybe a version issue but it may not and I could be in the same situation, unless there is a nugget of information from someone who has thankfully read this far!
Thanks for your interest


rtel wrote on Sunday, May 22, 2011:

Well it sounds like you have done all the logical things.  There should, in theory, be no problem with calling xQueueCreate() from main, and storing the returned value in a globally defined variable of type xQueueHandle.  It is a common thing to do.

I do not think there should be a problem with the FreeRTOS version number either - although as you said it is a community contributed port, I cannot vouch for the port.  It is still, however, worth updating to the latest FreeRTOS source files.

Outside of queue.c, a variable of type xQueueHandle is a pointer to void.  Inside queue.c, a variable of type xQueueHandle is a pointer to a queue data structure.  This is just for data hiding purposes.  It is possible that either the variable of type xQueueHandle, or the data structure being pointed to by the xQueueHandle variable, is being corrupted between the queue being initialised, and the queue being used in the task.  This is particularly possible if the linker script is not defined correctly, or if you you using a dynamic memory allocator that is not checking its boundaries.

Can you inspect the value of the xQueueHandle variable after the queue is created in main() (you say you are doing that already to check the queue was created correctly), and then inspect the same variable at the point the queue is used in the task.  The value should not change between these two points as it is just a pointer to a data structure.  If the value is the same, then the next thing to do would be to see if the data structure being pointed to changes, but that would be more complex.

If this does not highlight the problem, could you replicate the problem in a really, really, small and trivial example and post the code here?  (using the codify tags so the formatting remains correct).  This example could just have a single file that declares the global variable, have main do nothing but create the queue, create a task that uses the queue, then start the scheduler.  The task can do nothing but write to the queue, then read back from the queue to check it reads back the same value.  Stepping that up a bit, if it works ok, you could change it to have two tasks, one that writes to the queue and one that blocks waiting to read from the queue, as that would exercise a bit more code.


cmauler wrote on Sunday, May 22, 2011:

Thank you Richard very much for your thoughtful response

>>Well it sounds like you have done all the logical things
I tried to note down most of the stuff and leave out the more bazaar stuff like “does static make a difference”?…

>>I cannot vouch for the port
I took most of it as “in the spirit” which gives you something to study when you are learning. The official port demonstrator has too much going on when you are just trying to learn the basics

>>worth updating to the latest
Been working on that. As I am running it on the chip, I have a few files to get some basic I/O configured but after I #include’d all the header files I still cannot get a build, most frustrating.
I assume the MPLAB based examples are dated as they have compilation problems and therefore so weakened in an educational capacity

>>data hiding purposes
I’ll assume it won’t make understanding easier

>>The value should not change between these two points
I have now checked the size of the queue just after created (in main) and it’s heart warmingly zero but before it is used in the task uxQueueMessagesWaiting returns with 67 which is erroneous as the queue created was eight items of size uint32_t. I do more inspecting of values once things build

>>really, really, small and trivial example and post the code
I thought it would be more effective to relate the results as I had so closely followed an example but had to include bespoke stuff to get the data out. The refreshed version is to preserve the lines of interest from the example

Spurred on by your marvellous reply I am urgently trying to get it to build but I don’t know how to solve linker? problems (below)


–fragments as MPLAB hampers copying out of the output window
{memory tables}
…undefined reference to `xQueueGenericSend’
…undefined reference to `vTaskDelayUntil’
…undefined reference to `xQueueCreate’

Link step failed.

cmauler wrote on Monday, May 23, 2011:

After a nights sleep, I realised which setting in the project that was causing the linker problems
Now the queue test can proceed

davedoors wrote on Monday, May 23, 2011:

To help everybody else on this list, please give details of what fixed the problem. Which linker option was it?