|
|
View previous topic :: View next topic |
Author |
Message |
equack
Joined: 21 Sep 2009 Posts: 21
|
strcpy() disables interrupts? |
Posted: Mon Aug 23, 2010 6:31 pm |
|
|
I tried to post this earlier but it didn't seem to take. Let's try it again:
The strcpy() function disables interrupts (see listing excerpt below). So does the sprintf() function. Is there any way to prevent this? I can't miss an interrupt. I would like to be able to use sprintf().
Thank you!
Code: |
.................... strcpy(&console[116],"EQUACK 80"); // centered at the top of the screen
005FA: MOVLW console>>8
005FC: MOVWF FSR0H
005FE: MOVLW console+-140
00600: MOVWF FSR0L
00602: MOVFF INTCON,@@26
00606: BCF INTCON.GIE
00608: MOVLW 00
0060A: RCALL 010C
0060C: TBLRD*-
0060E: TBLRD*+
00610: MOVF TABLAT,W
00612: MOVWF POSTINC0
00614: IORLW 00
00616: BNZ 060E
00618: BTFSC @@26.7
0061A: BSF INTCON.GIE |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Aug 24, 2010 3:47 am |
|
|
What chip?.
There is an erratum on some chips regarding the table instructions and interrupts. Looks like a fix for this.
Remember you won't 'miss' an interrupt, it'll just be delayed for a few machine cycles.
Best Wishes |
|
|
equack
Joined: 21 Sep 2009 Posts: 21
|
strcpy() disables interrupts? |
Posted: Tue Aug 24, 2010 10:13 am |
|
|
Chip is 18F26K20 running at 57.27 mHz
14.318 mHz crystal using fuse H4 for 4X PLL
Compiler is 4.095, 49243 (newer ones are broken- unrelated to this)
"it'll just be delayed for a few machine cycles".
That's the point. I cannot delay interrupts for a few machine cycles. I wrote the ISR in assembly. I had to use this PIC because it can run at up to 64mHz- earlier PICs aren't fast enough. I had to use NOPs in order to get the ISR timing just right.
And I got it working perfectly.
It stopped working when I added a sprintf() to my non-interrupt code. I thought sprintf() was the culprit so I switched to strcpy(). No Joy.
Is there a workaround? Can I link with an older version of the library or something?
I don't want to switch compilers but that's where this is headed. |
|
|
equack
Joined: 21 Sep 2009 Posts: 21
|
another sprintf() issue |
Posted: Tue Aug 24, 2010 11:39 am |
|
|
I found another serious problem with sprintf().
This produces correct output:
Code: |
for(;;)
{
sprintf(&console[CONSOLELAST],"Line: %ld, Random: 0x%04lx",count++,rand());
}
output:
...
Line: 14, Random: 0x3886
Line: 15, Random: 0x050b
Line: 16, Random: 0x6de5
...
|
This does not:
Code: |
char formstring[]="Line: %ld, Random: 0x%04lx";
for(;;)
{
sprintf(&console[CONSOLELAST],formstring,count++,rand());
}
output:
...
Line: %ld, Random 0x%04lx
Line: %ld, Random 0x%04lx
Line: %ld, Random 0x%04lx
|
The help file says:
Quote: |
sprintf(string, cstring, values...)
...
string is an array of characters
cstring is a constant string or an array of characters null terminated.
Values are a list of variables separated by commas.
|
sprintf() does no formatting if cstring is an array of characters. It only does formatting if cstring is a constant string. |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
Re: another sprintf() issue |
Posted: Tue Aug 24, 2010 12:12 pm |
|
|
equack wrote: | I found another serious problem with sprintf().
This produces correct output:
Code: |
for(;;)
{
sprintf(&console[CONSOLELAST],"Line: %ld, Random: 0x%04lx",count++,rand());
}
output:
...
Line: 14, Random: 0x3886
Line: 15, Random: 0x050b
Line: 16, Random: 0x6de5
...
|
This does not:
Code: |
char formstring[]="Line: %ld, Random: 0x%04lx";
for(;;)
{
sprintf(&console[CONSOLELAST],formstring,count++,rand());
}
output:
...
Line: %ld, Random 0x%04lx
Line: %ld, Random 0x%04lx
Line: %ld, Random 0x%04lx
|
The help file says:
Quote: |
sprintf(string, cstring, values...)
...
string is an array of characters
cstring is a constant string or an array of characters null terminated.
Values are a list of variables separated by commas.
|
sprintf() does no formatting if cstring is an array of characters. It only does formatting if cstring is a constant string. |
I have noticed that too (w/ 4.104 compiler PCH). If you do not pass a constant string for the format string it will ignore the formatting and just display it. I'm pretty sure they all do it: printf, sprintf, etc. Anything that takes a format string must be passed a const char string. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 24, 2010 12:25 pm |
|
|
That's an older version. Newer versions are different.
Here's my test program. It's got your strcpy line, and it's got an interrupt
routine so the compiler will be prompted to disable interrupts (if it's going
to do that).
Code: |
#include <18F26K20.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#int_ext
void int_ext_isr(void)
{
char c;
c = 0x55;
}
//==========================
main()
{
int8 console[200];
strcpy(&console[116],"EQUACK 80");
while(1);
} |
Here's the vs. 4.095 code. It does a BCF on the GIE bit. That's what
you got.
Code: |
.................... strcpy(&console[116],"EQUACK 80");
000F2: CLRF FSR0H
000F4: MOVLW console+116
000F6: MOVWF FSR0L
000F8: MOVFF INTCON,@@E0
000FC: BCF INTCON.GIE // Disable global interrupts
000FE: MOVLW 00
00100: RCALL 009E
00102: TBLRD*-
00104: TBLRD*+
00106: MOVF TABLAT,W
00108: MOVWF POSTINC0
0010A: IORLW 00
0010C: BNZ 0104
0010E: BTFSC @@xE0.7
00110: BSF INTCON.GIE // Re-enable them if they were enabled before
|
Here I've re-compiled it with vs. 4.111 (the latest). It doesn't do it.
Code: |
.................... strcpy(&console[116],"EQUACK 80");
000F8: CLRF FSR0H
000FA: MOVLW console+116
000FC: MOVWF FSR0L
000FE: MOVLW 00
00100: RCALL 00AE
00102: TBLRD*-
00104: TBLRD*+
00106: MOVF TABLAT,W
00108: MOVWF POSTINC0
0010A: IORLW 00
0010C: BNZ 0104
|
Also, I commented out the #nolist line at the top of the 18F26K20.h file
so it would show me all the code in the .LST file. Here's the text fetch
code that it calls at AE. It doesn't disable interrupts either.
Code: |
000AE: CLRF TBLPTRH
000B0: ADDLW BE
000B2: MOVWF TBLPTRL
000B4: MOVLW 00
000B6: ADDWFC TBLPTRH,F
000B8: TBLRD*+
000BA: MOVF TABLAT,W
000BC: RETURN 0
000BE: DATA 45,51
000C0: DATA 55,41
000C2: DATA 43,4B
000C4: DATA 20,38
000C6: DATA 30,00
|
I suggest that you upgrade.
Quote: |
char formstring[]="Line: %ld, Random: 0x%04lx";
for(;;)
{
sprintf(&console[CONSOLELAST],formstring,count++,rand());
}
|
Read this post about why variable format strings don't work in CCS:
http://www.ccsinfo.com/forum/viewtopic.php?t=34513&start=9 |
|
|
equack
Joined: 21 Sep 2009 Posts: 21
|
|
Posted: Tue Aug 24, 2010 1:46 pm |
|
|
Interrupt problem solved with upgrade to compiler 4.111.
Thank you! |
|
|
|
|
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
|