Tasks, Queues and Priorities

try to have two tasks and a queue. The producer runs on a lower priority than the consumer, but the consumer has to carry out some hardware related stuff which includes timeouts, waiting for the adc making 500 samples at low speed sampling rate for instance. to get this up step by step, I replaced the hardware stuff by delays. Whats going on now, as I check it out using the debugger and breakpoints. 1. Some ticket entered the queue and the consumer starts over immediately, bevause he hase the higher priority.
2. Consumer reaches the first point of waiting
3. The producer starts again and throw in another ticket, that ok
4. The consumer immediately starts at the beginnung again, not finishing the outstanding work, getting the new ticket and …. Ok, I run the sample for some time waiting for a crash because this behavior should lead to memory problems, but It works. My question now: Is this concept bullshit, or is the debugger misleading me or whats going on here? With best regards Gerhard

Tasks, Queues and Priorities

In other words: The second queue-event releases your task from the block-state to which it was send with a delay. If this is actually the case that would be a major bug in FreeRTOS. A task blocked by a delay may only be released after termination of the time constraint. The only way around this, I know of, is an example in the reference manual where the task is released earlier by calling vTaskSuspend() and vTaskResume() before the actual time limit is reached. Queue-events shouldn’t have any impact on delays. Since such a prominent bug would’ve been noticed, the problem is probably at your end. My best guess would be that the debugger somehow currupts the behaviour.

Tasks, Queues and Priorities

I need to get a better understanding of the question.
1. Some ticket entered the queue and the consumer starts over immediately, bevause he hase the higher priority.
Ok, sounds good so far.  A high priority task is blocked on a queue, waiting for data.  Data is posted to the queue by a low priority task, causing the higher priority task to unblock (data is in the queue), and, as it has the higher priority, preempt the task that posted to the queue.  Now the high priority task is running.
2. Consumer reaches the first point of waiting
The consumer, being the higher priority task, is blocked for a fixed period.  It enters the Blocked state, which allows the lower priority producer task to execute again.
3. The producer starts again and throw in another ticket, that ok
The low priority writes to the queue again, but this time there is nothing blocked on the queue as the higher priority consumer is just delaying for a fixed period (not delayed on the queue, just delaying).  Therefore the low priority task should be able to write to the queue, not get preempted as the write does not unblock anything, and just continue. This scenario of course could result in the queue becoming full – if tasks are writing to the queue but the only task that can read from the queue is blocked doing something else.
4. The consumer immediately starts at the beginnung again, not finishing the outstanding work, getting the new ticket and ….
Up to now I have understood everything, but this bit does not make sense to me, or I have misunderstood what you are saying.  What should happen is the consumer completes is delay, leaves the Blocked state, then continues with whatever the next thing in its implementation is – which might be to read from the queue again. What you seem to be saying is that the task just starts from the beginning of its implementation again?  That can only point to a system crash/reset.  The most likely cause for that would be a stack overflow.  Do you have stack overflow checking switched on? This assumes you are using an official port.  If not, I cannot really comment as there may be a bug in the (unofficial) port layer.  All the official ports goes through fairly extensive testing that I would hope would highlight such a bug (not that anything is 100% certain of course). Regards.

Tasks, Queues and Priorities

….just to add some more.  Which port are you using?  If it is a Cortex-M3 port I could suggest also that you double check your interrupt priorities having looked at item three here: http://www.freertos.org/FAQHelp.html Regards.

Tasks, Queues and Priorities

One thing to watch out for is that debuggers can get confused with task switches. It sounds like while the consumer was “paused” you traced through the producer, but during that time the consumer probably finished it’s delay and started back up, but no breakpoint was set for it any more (the breakpoint following the producer), and then finished its operations. If you use a debugger to “step” through a task, you MUST avoid stepping into any function that might be called by multiple threads (including most of FreeRTOS) or you may “jump threads” in the stepping and the thread you are tracing runs on ahead. What happens with stepping is that you can (normally will) get a timer interrupt when you step (which the stepping normally doesn’t follow), and if that task switches, that can bypass the debugger which put a breakpoint on the next instruction it thought would run, so other tasks run until you get back to task you started from (or any other task that reaches that address). If you end up with a different task than the one you started with, if you ever follow it on a path the first task doesn’t take, the first task now run free. You can set breakpoints and watch it progress.