From: Arkadi S. <ar...@me...> - 2008-08-07 20:30:02
|
Hello. I'm having troubles with a custom delay functions that never returns. Same code compiled with PICC Lite compiler perform as expected. This code works fine: void delay_ms(unsigned int ms) { int i; while (ms--) for (i = 0; i < 440; ++i); } But the delay_ms() below never returns and prints endless line of 'd'-s. #define TMR0_PER_MS 20 // TMR0_PER_MS/(20MHz/4 clocks per cycle/256 prescaler) = 0.001s (1ms) void tx(char c) { while (!TXIF); // wait for transmitter to become free TXREG = c; } unsigned char start_timer(void) { unsigned char tmr; T0IF = 0; // here is a short window of TMR0 overflow tmr = TMR0; if (tmr != 255) T0IF = 0; return tmr; } int time_since(unsigned char tmr_start) { int tm; if (T0IF) { // if timer overflow tm = 255 - tmr_start + TMR0; } else { tm = TMR0 - tmr_start; if (tm < 0) // overflow happened just after T0IF is read tm = 255 - tmr_start; } return tm; } void delay_ms(unsigned int ms) { unsigned char tmr_start, debug_skip_i = 0; while (ms--) { tmr_start = start_timer(); if (!debug_skip_i++) tx('d'); while (time_since(tmr_start) < TMR0_PER_MS); } } It doesn't matter how big is the delay_ms() argument: 5000 or 50 - it loops endlessly in while(ms--). Changing delay_ms() argument to unsigned char make it exit while() loop, but the resulting delay is wrong and much less than required. Ie. int i; for (i = 0; i < 100; ++i) delay_ms(100); produces almost no delay. The start_timer()/time_since() might look like an overkill but I use them in other parts of the code. Here are the assembler listings generated by the compiler: --------------------------------------- 1. simple but good _delay_ms ;Function start ; 2 exit points ; .line 96; "pic-fire.c" void delay_ms(unsigned int ms) BANKSEL r0x1012 MOVWF r0x1012 MOVF STK00,W MOVWF r0x1013 _00137_DS_ ; .line 108; "pic-fire.c" while (ms--) for (i = 0; i < 440; ++i); BANKSEL r0x1013 MOVF r0x1013,W MOVWF r0x1014 MOVF r0x1012,W MOVWF r0x1015 MOVLW 0xff ADDWF r0x1013,F BTFSS STATUS,0 DECF r0x1012,F MOVF r0x1014,W IORWF r0x1015,W BTFSC STATUS,2 GOTO _00143_DS_ MOVLW 0xb8 MOVWF r0x1014 MOVLW 0x01 MOVWF r0x1015 _00142_DS_ MOVLW 0xff BANKSEL r0x1014 ADDWF r0x1014,F BTFSS STATUS,0 DECF r0x1015,F MOVF r0x1014,W IORWF r0x1015,W BTFSS STATUS,2 GOTO _00142_DS_ GOTO _00137_DS_ _00143_DS_ RETURN ; exit point of _delay_ms --------------------------------------- 2. using timer, wrong _delay_ms ;Function start ; 2 exit points ; .line 85; "pic-fire.c" void delay_ms(unsigned int ms) BANKSEL r0x1012 MOVWF r0x1012 MOVF STK00,W MOVWF r0x1013 ; .line 88; "pic-fire.c" while (ms--) { CLRF r0x1014 _00142_DS_ BANKSEL r0x1013 MOVF r0x1013,W MOVWF r0x1015 MOVF r0x1012,W MOVWF r0x1016 MOVLW 0xff ADDWF r0x1013,F BTFSS STATUS,0 DECF r0x1012,F MOVF r0x1015,W IORWF r0x1016,W BTFSC STATUS,2 GOTO _00145_DS_ ; .line 89; "pic-fire.c" tmr_start = start_timer(); CALL _start_timer BANKSEL r0x1015 MOVWF r0x1015 ; .line 90; "pic-fire.c" if (!debug_skip_i++) MOVF r0x1014,W MOVWF r0x1016 INCF r0x1014,F MOVF r0x1016,W BTFSS STATUS,2 GOTO _00139_DS_ ; .line 91; "pic-fire.c" tx('d'); MOVLW 0x64 CALL _tx _00139_DS_ ; .line 92; "pic-fire.c" while (time_since(tmr_start) < TMR0_PER_MS); BANKSEL r0x1015 MOVF r0x1015,W CALL _time_since BANKSEL r0x1017 MOVWF r0x1017 MOVF STK00,W MOVWF r0x1016 ;signed compare: left < lit(0x14=20), size=2, mask=ffff MOVF r0x1017,W ADDLW 0x80 ADDLW 0x80 BTFSS STATUS,2 GOTO _00153_DS_ MOVLW 0x14 SUBWF r0x1016,W _00153_DS_ BTFSC STATUS,0 GOTO _00142_DS_ ;genSkipc:3225: created from rifx:0xbfb4db30 GOTO _00139_DS_ _00145_DS_ RETURN ; exit point of _delay_ms |
From: Jean-Paul <tch...@fr...> - 2008-08-08 06:41:28
|
Hi, could it be that tmr has to be declared volatile? Worth a try. Regards JP On Thu, 07 Aug 2008 22:25:48 +0200, Arkadi Shishlov <ar...@me...> wrote: > unsigned char start_timer(void) > { > unsigned char tmr; > T0IF = 0; > // here is a short window of TMR0 overflow > tmr = TMR0; > if (tmr != 255) > T0IF = 0; > return tmr; > } -- NEVER jump into a LOOP! |
From: Raphael N. <rn...@we...> - 2008-08-14 21:55:08
|
Hi Arkadi, > Hello. > I'm having troubles with a custom delay functions that never returns. Same code > compiled with PICC Lite compiler perform as expected. Could you try to update to a recent SDCC version (snapshot) and compile your source file with --nooverlay (newly supported option for the pic14 port, since svn r5209, committed on 2008-08-10)? This should both blow up data memory usage and solve your problem. Then please report whether the problem is solved or not. A second workaround is to split your source into multiple files and have them linked afterwards. Move tx and delay into separate files solves this particular problem as well; however, any two functions of which one calls the other can potentially show the same behavior (locals/temporary values of the two functions are allocated into the same registers, so that the called function corrupts the calling function's state, in your case, the loop counter...). If I am right, this is the same problem as "[ sdcc-Bugs-2023121 ] compiler improperly reuses registers - pic14", which is being worked on already. The solution will use more data memory than currently, but should do better in many cases than --nooverlay. Regards, Raphael |
From: Arkadi S. <ar...@me...> - 2008-08-20 16:16:07
|
Raphael Neider wrote: > Hi Arkadi, >> I'm having troubles with a custom delay functions that never returns. Same code >> compiled with PICC Lite compiler perform as expected. > > Could you try to update to a recent SDCC version (snapshot) and compile > your source file with --nooverlay (newly supported option for the pic14 > port, since svn r5209, committed on 2008-08-10)? This should both blow > up data memory usage and solve your problem. Then please report whether > the problem is solved or not. The code works correctly with SDCC version 2.8.3 #5216 and --nooverlay option. Does not work without --nooverlay. |
From: <Mauricio_Costa@Dell.com> - 2008-08-20 16:57:55
|
I have issue similar (maybe it would be in a separated thread) but the bottom line is SDCC might have issues to process loops (AFAIK for PIC14 architecture). Let's embody this e-mail... I have in my personal lib a function as shown: ... // write string to LCD void lcd_puts(char *str) { char *p; for(p=str,*p,p++) // loop str while *p!=0; lcd_write(T_DATA,*p);// output char to lcd } ... When I call passing a string to it, it only outputs the 1st char... I'm using PIC16F876A and same behavior for my PIC16F628 and 16F88. This same code works fine (as is) when ported to MikroC. Regards, Mauricio -----Original Message----- From: sdc...@li... [mailto:sdc...@li...] On Behalf Of Arkadi Shishlov Sent: quarta-feira, 20 de agosto de 2008 13:08 To: sdc...@li... Subject: Re: [Sdcc-user] pic14 16f628a sdcc 2.8.0 never ending loop -mis-compilation? Raphael Neider wrote: > Hi Arkadi, >> I'm having troubles with a custom delay functions that never returns. Same code >> compiled with PICC Lite compiler perform as expected. > > Could you try to update to a recent SDCC version (snapshot) and compile > your source file with --nooverlay (newly supported option for the pic14 > port, since svn r5209, committed on 2008-08-10)? This should both blow > up data memory usage and solve your problem. Then please report whether > the problem is solved or not. The code works correctly with SDCC version 2.8.3 #5216 and --nooverlay option. Does not work without --nooverlay. ------------------------------------------------------------------------ - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Sdcc-user mailing list Sdc...@li... https://lists.sourceforge.net/lists/listinfo/sdcc-user |
From: <Mauricio_Costa@Dell.com> - 2008-08-20 17:00:30
|
Sorry guys, consider this as the non working code (when writing that e-mail, I typed wrongly commas instead of semi colons)... // write string to LCD void lcd_puts(char *str) { char *p; for(p=str;*p;p++) // loop str while *p!=0; lcd_write(T_DATA,*p);// output char to lcd } -----Original Message----- From: Costa, Mauricio Sent: quarta-feira, 20 de agosto de 2008 13:56 To: sdc...@li... Subject: RE: [Sdcc-user] pic14 16f628a sdcc 2.8.0 never ending loop -mis-compilation? I have issue similar (maybe it would be in a separated thread) but the bottom line is SDCC might have issues to process loops (AFAIK for PIC14 architecture). Let's embody this e-mail... I have in my personal lib a function as shown: ... // write string to LCD void lcd_puts(char *str) { char *p; for(p=str;*p;p++) // loop str while *p!=0; lcd_write(T_DATA,*p);// output char to lcd } ... When I call passing a string to it, it only outputs the 1st char... I'm using PIC16F876A and same behavior for my PIC16F628 and 16F88. This same code works fine (as is) when ported to MikroC. Regards, Mauricio -----Original Message----- From: sdc...@li... [mailto:sdc...@li...] On Behalf Of Arkadi Shishlov Sent: quarta-feira, 20 de agosto de 2008 13:08 To: sdc...@li... Subject: Re: [Sdcc-user] pic14 16f628a sdcc 2.8.0 never ending loop -mis-compilation? Raphael Neider wrote: > Hi Arkadi, >> I'm having troubles with a custom delay functions that never returns. Same code >> compiled with PICC Lite compiler perform as expected. > > Could you try to update to a recent SDCC version (snapshot) and compile > your source file with --nooverlay (newly supported option for the pic14 > port, since svn r5209, committed on 2008-08-10)? This should both blow > up data memory usage and solve your problem. Then please report whether > the problem is solved or not. The code works correctly with SDCC version 2.8.3 #5216 and --nooverlay option. Does not work without --nooverlay. ------------------------------------------------------------------------ - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Sdcc-user mailing list Sdc...@li... https://lists.sourceforge.net/lists/listinfo/sdcc-user |