I'm having a major problem with printf. The code is set up so that the printf's are used in subroutines, 1 maybe 2 deep. There is a separate RTC routine running that has nothing to do with the printf subroutines.
Here is the problem,
if the interrupt is off printf works OK,
if the RTC interrupt is running, the printf prints a few characters correctly then takes off in an endless stream of garbage, but repeating pattern. The printf never returns once this starts.
Here is what has been done,
printf's pointer requirements have been minimize by breaking complex lines into separate lines
RTC interrupt rate has ben reduced, in case there was a cpu speed resource issue
Xdata ram reserve has been increased to 700 bytes.
I suspect there is some sort of ram conflict occurring, but I am having no luck in figuring it out. Has any one seen the printf source code.
The only solution will be to write a totally new printf, but this si a big job with teh format specifiers and there is likely not enough memory.
any help appreciated
are the two interrupts at different priorities with the same 'using'?
I don't think there are two interrupts.
The original text tries to say that printf() is called from one or two levels deep subroutines. And if the RTC interrupt is enabled then the printf() call will take a stage dive.
So the question is if the interrupt handler either only makes use of unique, private, resources or if there is some resource sharing where the interrupt clobbers RAM or registers needed by printf() and helper functions.
But the OP needs to tell much more information about compilation options, and what register banks the interrupt is using and if one or more register banks are used to store variables, ...
re the questions
ONLY 1 interrupt, priority 1, no other interrupts no shared resources at all. tick counter is accessed by mainline via dedicated semaphore flag
register bank not specified so registers are stored on the stack AND POP OFF THE STACK CORRECTLY
full compiler options
.lst file include symbols include asm code include conditional
enable ansi promotion
level 8 optimization favor fast code
large xdata large 64k
command line SB CD Large INCDIR...
If that's to say that you do not have a "using" specifier on your interrupt service routine, that's a rather bad idea. Not only is it pointlessly slow, it also increases stack consumption by quite a bit --- and what you see in your program practically reeks of stack overflow.
specifying the stack register (with using 1,2,3 ) has no effect, reverted back stack based in attempt to debug, but no effect - exactly the same result
All variables used in isr and main program are global, so not much in the way of stack use.
scanf and printf are notorious stack fiends, I can't speak to the Keil 8051 implementation, but the ARM ones regularly have the stack and heap crash into each other with the default allocations.
set a breakpoint at the top of main fill the stack with some known value, run the code. then, after a while, verify that the last stack location still holds your 'filler'
OK, it is confirmed as NOT a stack problem. It is caused by access to the SPI ports while printf is in process. Still trying to figure it out. It is a software corruption, not a hardware issue from what I can see, perhaps a SFR issue. Have to look at the assembly code to see whats going on. Also found bug in compiler relating to setting the TCON SFR while in a subroutine. Likely something to do with the optimizer but a very nasty bug as it is very hard to find but only likely affects the silicon labs part due to the special SFR bit in the register.
Does anyone here have experience with this compiler and silicon labs parts?
Also found bug in compiler relating to setting the TCON SFR while in a subroutine.
It's highly unlikely that the C51 compiler has a bug that directly affects TCON, or a bit within it.
I'd say, from what you're describing, that it is possibly a function overlay issue; with the variables of the mainline code and interrupt maybe using the same memory locations. Check the MAP file to determine variable addresses for mainline and ISR use.
Treat comments about the use of using carefully. Using register banks is not always the clear winner, and not using them can allow the compiler (and you) to carry out other optimizations.
first what chip do you use, recommending setting a breakpoint in an old 80c51 does not make sense second, it COULD be that you have an enabled interrupt with no ISR third, it would be beneficial if you posted your code