View previous topic :: View next topic |
Author |
Message |
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
Can I have 2 copies of printf() to avoid re-entrancy? |
Posted: Mon Aug 04, 2008 1:02 pm |
|
|
This must be a common problem:
In my main loop I'm doing a lot of LCD updating, with heavy use of the printf() statement to send various formats of variables to the display in ascii form.
At the same time, in an interrupt routine, I'm sending control messages to a motor controller that requires ascii character strings for numeric values. So I'm making heavy use of the printf() statement there as well.
When I compile, I get "Warning 216: Interrupts disabled during call to prevent re-entrancy: (@PRINTF_L32U_75)". My code is slightly glitchy from time to time, and I attribute it to occassionally inconsistent interrupt response. When I disable the LCD routines, the problem goes away.
So, I think I need two copies of the printf() statement -- one for use in interrupts, one for use in the main loop. The processor has plenty of rom and ram left, so space is no object. How would this be done?
Thanks for your help!
Jim |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Mon Aug 04, 2008 1:08 pm |
|
|
One thing to note about ISR's, never, ever place a printf() inside one. An ISR is meant to be short and sweet. In other words, get in, do something quick like setting a flag, incrementing something, storing a variable, etc. then get out.
A printf(), in an ISR, will cause a variety of problems. If you need something printed when an ISR is called it is best to set a flag in the ISR and then compare that flag in the main body. If the flag has been set then print what you need.
Also, don't place delays in an ISR either.
Ronald |
|
|
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
|
Posted: Mon Aug 04, 2008 1:28 pm |
|
|
I'm aware of these issues.
This design makes extensive use of high and low priority interrupts. Pretty much everything that is important happens within an interrupt. A timer0 interrupt triggers motor control packets every 11ms. Even with the printf() statement in there, it takes very little time to complete. Nothing in the main loop is more important than the timer0 interrupt -- it will be no problem if the interrupt takes a substantial period. Functions that *are* more important are configured with higher priority. It's working just fine, and would be perfect if it weren't for the printf() contention.
Your suggestion of setting a flag may work -- I will give it a try.
But I'm still curious about ways to have more than one iteration of the printf() function, or any other built-in function. Is this possible?
Jim |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
|
Posted: Mon Aug 04, 2008 1:38 pm |
|
|
Actually... I don't think the flag suggestion will work. There are several low-priority routines in the main loop. The display update routine, in particular, is complex and may take longer than 11ms to complete. There are also various ambient temperature checks, keypad read, and other non-time-critical stuff.
I need to know that motor control messages always go out, every 11ms, without fail. Hence, the timer interrupt.
The motor controller requires ascii messages to be sent, including numeric values as ascii. Hence the need to use printf() in the interrupt routine.
I can't ensure that the main loop will always ready to jump whenever the flag is set. With the current solution, I can modify and expand the user-interface (main loop stuff) without ever worrying about background functions being on time.
Jim |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Mon Aug 04, 2008 2:07 pm |
|
|
If you need to send out a message from a timer interrupt, then you could create your own minimal formating functions that you call only from the interrupt code. You probably don't need the full force of printf anyway.
The conflict is between any static variables that the printf functions may use. If you were to install a second copy of printf, you would have to have the source code for the library and modify your printf2 function using different static variables. But I would try for my own formatting code first. _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
|
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
#org DEFAULT seems to do the trick -- THANKS!!! |
Posted: Mon Aug 04, 2008 2:33 pm |
|
|
Hey RL -- what you describe is exactly my backup plan -- I just wanted to avoid writing a new block of code, since the system I have written (using printf) is 99% good. (The contention is only sporadically evident).
It seems that the #org DEFAULT solution does the trick! I haven't seen a glitch since adding this. I can see the extra code in the LST file. Program memory has increased form 19% to 21%... a small price to pay at this point.
Thanks, folks -- this is an outstanding resource!!!
Most sincerely,
Jim |
|
|
|