Blocking, Semaphores and printf

leverett wrote on Saturday, September 25, 2010:

I “thought” I understood how the scheduler worked but I need some help.
I am running freertos on a pic32, using a starter kit and MPLAB.
I started with an example that creates two tasks that use semaphores to pass strings to a routine that “takes” the semaphore uses the printf command to print the string to the output. Works fine.

Now. I created a third task with a higher priority than the other two “printing” tasks. All it does is block for 1/2 second then unblock and toggles an led.

If I comment out the printf statement the led blinks once per second as expected. If I keep the printf statement in, the led blinks erratically. It appears that the printf statement doesn’t yield. There is no vTaskSuspendAll turning off the scheduler.

I would have expected it to yield to the blinker. Obviously I don’t understand something. Can anyone help explain this to me?

rtel wrote on Saturday, September 25, 2010:

How is printf() working, where is it printing too, and is it buffered or non buffered.

If you are printf()'ing down to the debugger then it can take a long time and will be uninteruptable, if it is non-buffered then even worse.  You are taking the execution out of the control of the scheduler and so I would not expect it to behave in a real time way.

If you are printf()'ing to an efficient UART driver, then that would be different, but it still depends on how the printf() library is implemented.

There are a lot of questions where people say I use printf() and evereything stops working, generally printf() is not something that I would expect to work well on a small microcontroller unless you are using a big stack, and the library function is redirected somewhere that is not going to effect the debuggers run time timing.


leverett wrote on Saturday, September 25, 2010:

Thanks this is a big help. I don’t know the answers really but what you are saying makes sense.
It is printing to the debugger. I had assumed it was interruptible BECAUSE an earlier example i was following had placed the printf inside a critical section (vTaskSuspenAll etc.) so I “assumed” they were showing me that the printf was interruptible. I think I will experiment a little with that example.

It does make sense that the printf “turns control” to the debugger and that the scheduler cannot interrupt the debugger since its not “part of the chip”.

Let me ask a follow up question. If I use any regular library routine that deals with on board (on chip) registers exclusively, no debugger is involved, then it seems to me that the only way it would be non-interruptible would be if the library routine turned off ALL interrupts. I understand maybe the library is non-reentrant and other “dangers” could exist BUT if a standard library turned off all interrupts for an excessive length of time it would cause serious problems with all programs not just FreeRTOS. Is this logic sound?

edwards3 wrote on Saturday, September 25, 2010:

Looks like sound logic to me, but I would not expect a standard C library to every mess with interrupts. Libraries that deal with peripherals (rather than ANSI libraries) probably will though. Also on some systems trap instructions are used to make calls to an underlying BIOS - DOS is an example of such a system.

leverett wrote on Saturday, September 25, 2010:

yes its all coming together for me now. Thanks for the help.

I did some experimenting to get a better idea of what is happening and you two are exactly correct.

in the example i was following, the one that made me “think” the printf was interruptible, there are two functions being used, a printf followed by a flush. My experiments are indicating that the printf does not yield (not sure about the flush since it runs so quickly) BUT it will yield between the printf and the flush (which makes sense) hence the need for the critical code section, to prevent yielding between the printf and the flush.

I’d say it ALL makes sense now, but I’m sure there are new discoveries for me … waiting patiently.

Thanks again.