printf() inside interrupt routine?

Is it ok to use printf twice inside my interrupt routine? It seems when I put the print statements in the interrupt routine stops getting called.

Thanks,
Nathan

This isn’t a good idea as printf is very slow taking up mS when interrupt code should be in uS. You would be better off to have the ISR flag a variable that calls a printf in your main loop.

The problem with that is the device interrupts at a very high speed. I think many, many, interrupts will happen before the 26ms loop runs.

But, what you suggested is actually what I’m doing right now.

Nathan

Why don’t you total the interrupts the device generates (like Kevin’s encoder code does) then use a printf in the slow loop?

Well, the “device” I mentioned is actually a camera… So the interrupts are bytes of tracking information.

Nathan

Why exactly do you need to print this data for every interrupt?

Why don’t you store the data in variables and print it every slow loop? This wouldn’t be as accurate, but 26.2 ms does give you a pretty good update rate.

usbcd36 - I was debugging my driver and wanted to be able to see every byte printed out in the order it arrived. Eventually I discovered this was not possible to do because of how blazingly fast the camera sends tracking data.

So I am essentially doing what you suggest, storing the values and printing out a select few in the slow loop.

Before today I was completely unaware of how processor intensive a printf statement is. I have a blinking LED that’s supposed to blink every 250 loops in the fast loop (which is around 250ms) and it works. But when I have even ONE printf statement in the fast loop it slows down to around one blink per second. So ONE printf statement slowed the program down by about a factor of 4! The IFI people weren’t kidding when they insctructed in the manual to use only short printf statements for debugging!

Thanks,
Nathan

If you reeeeealy need to do this, there any open source programs (google rs-232 monitor) that use the multiple serial ports on a PC to monitor a link. Most of them will log all the data coming and going to a text file.

HTH

Cool, thanks. I may look into that…

Why not send the data right back out the other serial port?

-Kevin

I thought that’s what printf did?

Printf converts the data you pass to it into a human-readable string format. For instance, the value 100 would be converted into the following three characters: ‘1’ ‘0’ ‘0’. What Kevin is suggesting is for you to simply send the byte values themselves out of the serial port. This can be done very quickly and won’t impact the ISR very much. You can then read those values into the computer and view them at your leisure, or record them and process them with an additional application (which may be quite useful for what it seems you’re trying to do).

As Adam pointed out, and assuming you’re using my serial port driver, it’s as simple as this:

 // first, find out how much data, if any, is present in 
 // serial port 1's received data queue?
 byte_count = Serial_Port_One_Byte_Count();
 
 // have we received any data?
 if(byte_count > 0)
 {
  // we have fresh data, so read each received byte one at a time
  for(j = 0; j < byte_count; j++)
  {
   // get the next data byte
   data = Read_Serial_Port_One();
 
   // send it out the other serial port
   Write_Serial_Port_Two(data);
 
  // work with camera data here
  }
}

-Kevin

Nathan,
It wouldn’t be a good idea to call a library routine like printf from inside an interrupt, even if the interrupt only happened every second. Most library routines are not re-entrant. If you were in the middle of a printf when the interrupt occurred, calling printf from inside the interrupt would mess up the printf in progress.

Bob

hmmm, I checked the MCC 18 library and found a couple routines that are non-reentrant as they appear that they might use some globals (e.g. strtokpgmram), but the majority of the library, including print/put/etc., appears to be re-entrant friendly by using only auto variables. The compiler will use .tmpdata and other managed resources, per usual, but interrupt routines should be saving the appropriate ones as needed already.

Do you know for certain that the library is non-reentrant? That would be good info to know as there are many library calls used that are not directly called by the user, like FXM3232 which is used for long x long multiplication.

Its still not a good idea to call printf() from within an interrupt routine due to the time delays associated with outputing the formated data, but not being re-entrant doesn’t appear to be a reason in this case. I easily could be wrong, but looking at printf, vprintf, etc down the call train didn’t reveal any obvious globals being referenced that would make the routine non-reentrant.