|
|
View previous topic :: View next topic |
Author |
Message |
C Turner
Joined: 10 Nov 2003 Posts: 40 Location: Utah
|
[Solved] Since when does "sprintf" disable interru |
Posted: Sat Oct 05, 2013 2:08 pm |
|
|
I recently updated from the V3/V4 compiler to V5.012 and was surprised when some code that I'd compiled for the PIC16F88 with the older versions blew up.
Tracking it down, I figured out that "sprintf" seems to be disabling global interrupts - and perhaps other things as well: The code below demonstrates.
If "break_it" is NOT defined, the "sprintf()" is not called and I see the interrupt operating by observation of pin B6
If you *do* define "break_it" then "sprintf()" seems to cause the ISR to quit - but if you un-comment the "enable_interrupts(GLOBAL)" it works again.
Anything that I'm missing? Why on Earth would it need to do this? Should I be bugging CCS about it?
Thanks,
CT
Code: |
//***
// Test program for CCS PICC V5.012
//
// Demonstrating the "sprintf()" seems to disable interrupts...
//
//*******************************************************************
//
#define break_it // if "break_it" is defined, the "sprintf()" in "main()" is used, breaking the code
//
//
#include <16F88.h>
//
#device ADC=10 *=16
//
#define PORT_A_ADDR 0x05 // port A address
#define PORT_B_ADDR 0x06 // port B address
//
#define PORT_A_TRIS 0 // set all pins to output mode
#define PORT_B_TRIS 0
//
#define TIMER2_SETUP setup_timer_2(T2_DIV_BY_1, 255, 2); // 1.953125 kHz ISR w/4 MHz xtal
//
#define BUFLEN 64 // size of buffer
//
// Standard xtal, no low-voltage programming, no master clear, watchdog, brownout,
// and power-up timer, PWM output on B0
//
#fuses XT, WDT, NOMCLR, NOPROTECT, PUT, NOLVP, BROWNOUT, CCPB0, NODEBUG, NOFCMEN
//
#use delay(clock=4000000, RESTART_WDT) // we are using a 4 MHz clock
//
#byte PORT_A = 5 // I/O addresses
#byte PORT_B = 6
//
//
#bit RES_B3 = PORT_B.3 // Toggled in "main()" to let us know it's working
#bit RES_B6 = PORT_B.6 // Toggled at ISR rate
//
#use fast_io(a) // the program is in complete control of I/O modes
#use fast_io(b)
//
unsigned char rxbuf[BUFLEN];
unsigned char txbuf[BUFLEN];
//
//
#int_timer2
void timer2_isr(void) // ISR rate - 1.953125 kHz, square wave at half that on B6
{
RES_B6 = !RES_B6; // toggle for ISR testing
}
//
//
void main(void)
{
PORT_A = 0;
PORT_B = 0;
//
set_tris_a(PORT_A_TRIS); //
set_tris_b(PORT_B_TRIS); //
//
setup_timer_2(T2_DIV_BY_1, 255, 2); // 1.953125 kHz ISR w/4 MHz xtal
//
setup_wdt(WDT_144MS); // Configure the watchdog for approx. 1/8 sec timeout
//
enable_interrupts(INT_TIMER2); // we only need timer2's interrupt
enable_interrupts(GLOBAL); // enable interrupts
//
//
#ifdef break_it
sprintf(txbuf, "Hello!\n\r");
#endif
// enable_interrupts(GLOBAL); // enable interrupts
//
//
while(TRUE) { // main loop
RES_B3 = !RES_B3; // toggle to let us know that it works
restart_wdt();
}
}
|
Last edited by C Turner on Thu Oct 24, 2013 10:04 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Oct 05, 2013 2:16 pm |
|
|
In this old thread, the sprintf disabling interrupts problem was solved by
upgrading the compiler. Can you test it the same as in that thread, and
tell us if it fails in the same way ?
http://www.ccsinfo.com/forum/viewtopic.php?t=43360 |
|
|
C Turner
Joined: 10 Nov 2003 Posts: 40 Location: Utah
|
Since when does "sprintf" disable interrupts? |
Posted: Sat Oct 05, 2013 5:42 pm |
|
|
Since the compiler with which this occurred (Version 5.012) *is* the newest version of the compiler as of today's date, I guess that I will report this "feature" and wait, doing work-arounds in the meantime:-)
Somehow searching on the suspiciously similar problem defied my attempts to find it, but it is interesting how the same sort of problem popped up again.
Thanks,
CT |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Oct 06, 2013 2:13 am |
|
|
I can confirm the observation.
It's apparently a new V5 bug, not present in the most recent V4 version. Both are disabling global interrupts
during sprintf() execution, but V5 fails to reenable it. -> Fall back to V4.141 with PIC16 projects for the time being. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Oct 06, 2013 11:36 am |
|
|
Ouch.....
I wonder if the behaviour changes if you tell the compiler to use the V4 interrupt handling instead?.
Not at my development system, so can't test this at present. However one critical change in V5, is that it reduces fractionally the registers saved when interrupts are called. I wonder if the 'reduction', is for a register/table, used in sprintf, hence disabling the interrupts here.
If so, going back to the old setting, might solve the problem, but is a 'stinker'....
Best Wishes |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Mon Oct 07, 2013 2:28 am |
|
|
No, changing to CCS4 mode still leaves the problem. :(
Looking at the assembler, the code to re-enable the interrupt is actually there. It is 'skipped' unless the top bit in INDF is set. It gets called for the very first character, but then not again, leaving the enable off.
Code: |
06D 1F80 BTFSS 0, 0x7
06E 2874 GOTO 0x74 //since bit is not set, jump past...
06F 1283 BCF 0x3, 0x5
070 1303 BCF 0x3, 0x6
071 178B BSF 0xb, 0x7 //This is the re-enable
072 1683 BSF 0x3, 0x5
073 1703 BSF 0x3, 0x6
074 1283 BCF 0x3, 0x5
|
It looks as if they meant to use a 0x80 after the string, as a flag to re-enable the interrupts, but this doesn't happen...
Needs to be reported to CCS, urgently.
It does exactly the same, if you use printf, linking to a buffer access routine. So:
Code: |
char * buffer_ptr;
void to_buff(char chr)
{
//routine to write a character to a string buffer
*buffer_ptr=chr;
buffer_ptr++;
}
//then send it with:
buffer_ptr=txbuf;
printf(to_buff, "Hello!\n\r");
|
As soon as the FSR register is setup, they disable interrupts.
So looks as if the fault will appear in a lot of other places as well....
In fact if you use the 'CCS cheat' of sending the string directly, so:
Code: |
buffer_ptr=txbuf;
to_buff("Hello!\n\r");
|
It does the same. So it is not sprintf, that is having the problem, but using FSR/INDF to access RAM.
If you switch to a PIC18, it doesn't happen.
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Oct 07, 2013 2:33 am |
|
|
Specifying #device ccs4 does not change the behaviour. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Mon Oct 07, 2013 3:52 am |
|
|
Tracking back a bit further, they copy the INTCON register to a scratch variable, but then clear the GIE bit, and copy it in again, overwriting the version with the GIE set. It is this version that gets copied back at the end of the routine.
Best Wishes |
|
|
C Turner
Joined: 10 Nov 2003 Posts: 40 Location: Utah
|
Since when does "sprintf" disable interrupts? |
Posted: Thu Oct 10, 2013 1:25 pm |
|
|
I reported this problem to CCS and this is what they sent back:
"The problem you reported has been fixed and will be in the next compiler release. "
As soon as >5.012 appears, I'll be trying this again.
CT |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Fri Oct 18, 2013 1:21 pm |
|
|
Thanks for reporting the bug.
I encountered it and narrowed it down to the sprintf() in my code.
Never got around to debugging it any further.
Ended up rewriting that with strcpy() and itoa()'s and got thru the project.
It sounds pretty serious, I rely on printf() and sprintf() pretty heavily.
It's very frustrating when such simple and previously reliable things break. |
|
|
C Turner
Joined: 10 Nov 2003 Posts: 40 Location: Utah
|
[Solved] Since when does "sprintf" disable interru |
Posted: Thu Oct 24, 2013 10:14 am |
|
|
I'm happy to report that as of 5.013, the bug where interrupts are disabled when sprintf() is used has been fixed.
I didn't test it extensively with all possible combinations, but I do know that various pieces of code using all sorts of permutations of printf and sprintf that had worked with 3.249 (very reliable!) and 4.023 (until recently, my newest V4 compiler) now seem to work just fine with 5.013.
* * *
One reason why I keep coming back to the CCS compiler (I've used it since '97) is that they *do* usually address the bugs - but only if they are reported!
Speaking of that, has anyone actually reported the "pullup" bug as described here?
http://www.ccsinfo.com/forum/viewtopic.php?t=51356&highlight=pullup
Thanks,
CT |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 24, 2013 10:33 am |
|
|
Yes, I reported it a few days ago and they fixed it in vs. 5.013. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Oct 25, 2013 3:03 am |
|
|
However, as this thread clearly demonstrates, the bugs don't always stay fixed :-( This is one that was fixed, then for whatever reason, reappeared and has just been fixed again.
While I hope it, and other fixed bugs, will never reappear, CCS's track record, on this bug and others, is such that I feel we would be foolish to assume that they won't. This is not a plus point for CCS unfortunately. Other compilers, of course, are available and may well be even worse in this regard! I am sufficiently happy with CCS C, particularly the productivity benefits it gives, that I am quite happy to forgive CCS such transgressions. I wish they'd yet their quality issues sorted however and release known good code rather than what are effectively betas all the time. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|