CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

[Solved] Since when does "sprintf" disable interru

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
C Turner



Joined: 10 Nov 2003
Posts: 40
Location: Utah

View user's profile Send private message

[Solved] Since when does "sprintf" disable interru
PostPosted: Sat Oct 05, 2013 2:08 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Oct 05, 2013 2:16 pm     Reply with quote

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

View user's profile Send private message

Since when does "sprintf" disable interrupts?
PostPosted: Sat Oct 05, 2013 5:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Oct 06, 2013 2:13 am     Reply with quote

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: 19513

View user's profile Send private message

PostPosted: Sun Oct 06, 2013 11:36 am     Reply with quote

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: 19513

View user's profile Send private message

PostPosted: Mon Oct 07, 2013 2:28 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 07, 2013 2:33 am     Reply with quote

Specifying #device ccs4 does not change the behaviour.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Oct 07, 2013 3:52 am     Reply with quote

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

View user's profile Send private message

Since when does "sprintf" disable interrupts?
PostPosted: Thu Oct 10, 2013 1:25 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Oct 18, 2013 1:21 pm     Reply with quote

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

View user's profile Send private message

[Solved] Since when does "sprintf" disable interru
PostPosted: Thu Oct 24, 2013 10:14 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Oct 24, 2013 10:33 am     Reply with quote

Yes, I reported it a few days ago and they fixed it in vs. 5.013.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Oct 25, 2013 3:03 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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