Freescale ARM port - determine the reason for a task being blocked

lajkabaus wrote on Tuesday, November 03, 2015:

Hello,

I am using Freescale’s FreeRTOS port and I am running several tasks on it, one being used for fetching sensors’ data and the other being used for communication.

What happens is, after some time, all my tasks become blocked. (see image).

Tasks' list

Without going into details, I’ll say only one thing that’s bothering me here; the task being used for fetching data (sensor_getData), while having the smallest priority, is waiting for a semaphore with the specified timeout value. He should unblock itself after a while, and yet, it seems like he is also blocked indefinitely with the rest of the other tasks! It’s so frustrating!

I am unable to logically conclude, at least from my understanding of the code, what exactly is blocking the tasks. So my question is this: how can I find the exact reason of a task being blocked, in general? Surely, this information is stored somewhere and can be accessed during debugging?

Thanks very much!

rtel wrote on Tuesday, November 03, 2015:

One thing you can do is use FreeRTOS+Trace, then look at the history. Another is view the call stack of sensor_getData to see where it is in the code (there is an Eclipse plug-in from Code Confidence to do that, but it is not free).

The image in your post does not show sensor_getData being blocked on a semaphore though - in fact it looks like it is blocked on a vTaskDelay() or vTaskDelayUntil() call (or possible a direct to task notification). Are you sure that does makes no other blocking API calls other than on the semaphore?

lajkabaus wrote on Wednesday, November 04, 2015:

Hey, thanks very much for prompt response!

I am still pretty new at all this, so I’ll take a look at all your options. I hope you dont mind me asking some stupid questions along the way.

Could you elaborate just a bit more on your second point, i.e. viewing the call stack the sensor_getData task? Is it possible without the plugin?

You’re right, I apologize! Before waiting on a semaphore, there is a call to the function vTaskDelay() for the duration of 500ms. The reason I didn’t mention it, is because I thought there was no way the task could be blocked indefinitely because of that… I’ll remove it and see what happens. May I also how did you come to the conclusion the task probably isn’t blocked on a semaphore?

Thanks again!

rtel wrote on Wednesday, November 04, 2015:

Could you elaborate just a bit more on your second point, i.e.
viewing the call stack the sensor_getData task? Is it possible
without the plugin?

There is a third party plug-in that can do this - search for “code
confidence freertos eclipse”.

You’re right, I apologize! Before waiting on a semaphore, there is a
call to the function vTaskDelay() for the duration of 500ms. The
reason I didn’t mention it, is because I thought there was no way the
task could be blocked indefinitely because of that… I’ll remove it
and see what happens.

It will not block indefinitely on that unless your tick interrupt is not
running. Is it possible the tick has stopped? If you view xTickCount
in the debugger is it still counting?

May I also how did you come to the conclusion
the task probably isn’t blocked on a semaphore?

The “Event Object” column in the image you posted shows that the task is
not blocked on an event object (such as a semaphore).

lajkabaus wrote on Thursday, November 05, 2015:

Hey, sorry for the delay, and thanks for your time!

I’ll try the evaluation version of that plugin and see how it goes, sound good!

It will not block indefinitely on that unless your tick interrupt is not
running. Is it possible the tick has stopped? If you view xTickCount
in the debugger is it still counting?

Yeah, the count is ticking, that definitely wasn’t the source of the problem.

I am not sure what was (or still is) causing the problem, but I’m pretty sure my inexperience plays a significant role in all this.

For example, the semaphore in question I’ve been using is, in fact, unnecessary, and I think I made some vicious circle between two tasks chasing each other’s tails.

To elaborate: this task (let’s call it task A for brevity’s sake) has a main purpose of filling the queue with sensor data, where the queue in question is blocking the (higher priority) task B in charge of sending data. Once it fills the queue, task A waits for the semaphore.

After task B, now being unblocked, finishes sending data, it will give to this semaphore, thus unblocking task A, and then returning to its wait to pull from the (now empty) queue.

This was the idea, anyway; task A to unblock task B (fill the queue), and task B to unblock task A (post to semaphore). I suspect I somehow succeded in creating a situation which was the polar opposite: one task was, for some reason, unable to unblock the other, thus rendering that task unable to unblock the first one.

I removed the semaphore - task A is now becoming blocked when the queue is full and that’s it. It seems to work for now. I’ll report here, should the issue reappear again.

P.S. I kinda lied; task A is not becoming blocked when the queue is full; since I am using Freescale’s port with its OSA wrappers, the OSA wrapper for posting to queue, in fact, doesn’t have the timeout argument. So I am just posting to the queue in an infinite loop untill I break upon the successful post.

davedoors wrote on Thursday, November 05, 2015:

No need for the semaphore, just use the FreeRTOS API directly. Task A can call xQueueSend() with a block period to automatically go into the blocked state when the queue is full and task B can call xQueueReceive() with a block period to automatically go into the blocked state when the queue is empty. If task a is in the blocked state is wakes automatically when the queue has space and if task b is in the blocked state it wakes automatically when the queue has data.

lajkabaus wrote on Thursday, November 05, 2015:

Unfortunately, it’s expected of me to use the wrappers, although I’ll try to persuade them otherwise. Other than that, the code still works, so that’s good news, phew! The mode of operation is basically what you described, that makes most sense.

P.S. I tried to use the plugin above, but didn’t really succeed in my attempt. It’s not really intuitive. Will try some more.