What am I doing wrong here? In the code below, when I compile it with SDCC 2.6.0, the outer loop is dropped. If I use a variable with changing values (e.g. while(count0 != 0) ), the outer loop is generated but it never terminates, even if I decrement the variable down to zero. I'm using a PIC16F628 (rev. 0). I'm just getting started with PIC, so please forgive my ignorance. Thanks for any help you can give.
Mac
The command line is:
sdcc -mpic14 -p16f628 SDCC_Test.c
Here is the C code:
#define __16f628
#include "pic/pic16f628.h"
// Set the __CONFIG word:
typedef unsigned int word;
word at 0x2007 __CONFIG = 0x3D90;
My initial post is incorrect. The code doesn't match the assembly. Let's try this again.
What am I doing wrong here? In the code below, when I compile it with SDCC 2.6.0, the outer loop is dropped. If I use a variable with changing values (e.g. while(count0 != 0) ), the outer loop is generated but it never terminates, even if I decrement the variable down to zero. I'm using a PIC16F628 (rev. 0). I'm just getting started with PIC, so please forgive my ignorance. Thanks for any help you can give.
Mac
The command line is:
sdcc -mpic14 -p16f628 SDCC_Test.c
Here is the C code:
#define __16f628
#include "pic/pic16f628.h"
// Set the __CONFIG word:
typedef unsigned int word;
word at 0x2007 __CONFIG = 0x3D90;
After quite a few hours of study and learning about how PICs and SDCC work, I found that the problem is not a missing while(1) loop. It actually appears to be related to bug report 1570934 (BANKSEL missing). A fix has been put in place (r4409) to solve the problem. I will investigate this further and post an additional bug report if necessary.
Mac
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Greetings,
What am I doing wrong here? In the code below, when I compile it with SDCC 2.6.0, the outer loop is dropped. If I use a variable with changing values (e.g. while(count0 != 0) ), the outer loop is generated but it never terminates, even if I decrement the variable down to zero. I'm using a PIC16F628 (rev. 0). I'm just getting started with PIC, so please forgive my ignorance. Thanks for any help you can give.
Mac
The command line is:
sdcc -mpic14 -p16f628 SDCC_Test.c
Here is the C code:
#define __16f628
#include "pic/pic16f628.h"
// Set the __CONFIG word:
typedef unsigned int word;
word at 0x2007 __CONFIG = 0x3D90;
static void main(void)
{
/* static unsigned char count0; */
static unsigned char count1;
static unsigned char count2;
TRISA = 0;
/* count0 = 0x01; */
while(1) {
PORTA = 0;
count1 = 0xff;
while(count1 != 0) {
count2 = 0x80;
while (count2 != 0) {
count2--;
}
count1--;
}
PORTA = 1;
count1 = 0xff;
while(count1 != 0) {
count2 = 0x80;
while (count2 != 0) {
count2--;
}
count1--;
}
count0--;
}
}
This is (what I think is) the relevant part of the assembly that is generated:
;--------------------------------------------------------
; udata
;--------------------------------------------------------
data_SDCC_Test udata
; .area DSEG (DATA)
udata_SDCC_Test_0 udata
r0x20 res 1
udata_SDCC_Test_1 udata
r0x21 res 1
;--------------------------------------------------------
; overlayable items in internal ram
;--------------------------------------------------------
; udata_ovr
;--------------------------------------------------------
; bit data
;--------------------------------------------------------
; .area BSEG (BIT)
;--------------------------------------------------------
; reset vector
;--------------------------------------------------------
STARTUP code
nop
pagesel __sdcc_gsinit_startup
goto __sdcc_gsinit_startup
code_init code
__sdcc_gsinit_startup
pagesel _main
goto _main
;--------------------------------------------------------
; code
;--------------------------------------------------------
code_SDCC_Test code
;***
; pBlock Stats: dbName = M
;***
;entry: _main ;Function start
; 2 exit points
;has an exit
;2 compiler assigned registers:
; r0x20
; r0x21
;; Starting pCode block
_main ;Function start
; 2 exit points
; .line 16; "SDCC_Test.c" TRISA = 0;
BSF STATUS,5
BCF STATUS,6
CLRF _TRISA
_00118_DS_
; .line 19; "SDCC_Test.c" PORTA = 0;
BCF STATUS,5
CLRF _PORTA
; .line 21; "SDCC_Test.c" while(count1 != 0) {
MOVLW 0x7f
BANKSEL r0x20
MOVWF r0x20
_00108_DS_
MOVF r0x20,W
BTFSS STATUS,2
GOTO _00134_DS_
GOTO _00110_DS_
_00134_DS_
; .line 23; "SDCC_Test.c" while (count2 != 0) {
MOVLW 0xff
MOVWF r0x21
_00105_DS_
MOVF r0x21,W
BTFSS STATUS,2
GOTO _00135_DS_
GOTO _00107_DS_
_00135_DS_
; .line 24; "SDCC_Test.c" count2--;
DECF r0x21,F
GOTO _00105_DS_
_00107_DS_
; .line 26; "SDCC_Test.c" count1--;
DECF r0x20,F
GOTO _00108_DS_
_00110_DS_
; .line 28; "SDCC_Test.c" PORTA = 1;
MOVLW 0x01
BCF STATUS,5
BCF STATUS,6
MOVWF _PORTA
; .line 30; "SDCC_Test.c" while(count1 != 0) {
MOVLW 0x7f
BANKSEL r0x20
MOVWF r0x20
_00114_DS_
MOVF r0x20,W
BTFSS STATUS,2
GOTO _00136_DS_
GOTO _00118_DS_
_00136_DS_
; .line 32; "SDCC_Test.c" while (count2 != 0) {
MOVLW 0xff
MOVWF r0x21
_00111_DS_
MOVF r0x21,W
BTFSS STATUS,2
GOTO _00137_DS_
GOTO _00113_DS_
_00137_DS_
; .line 33; "SDCC_Test.c" count2--;
DECF r0x21,F
GOTO _00111_DS_
_00113_DS_
; .line 35; "SDCC_Test.c" count1--;
DECF r0x20,F
GOTO _00114_DS_
RETURN
; exit point of _main
; code size estimation:
; 42+ 2 = 44 instructions ( 92 byte)
end
Greetings again,
My initial post is incorrect. The code doesn't match the assembly. Let's try this again.
What am I doing wrong here? In the code below, when I compile it with SDCC 2.6.0, the outer loop is dropped. If I use a variable with changing values (e.g. while(count0 != 0) ), the outer loop is generated but it never terminates, even if I decrement the variable down to zero. I'm using a PIC16F628 (rev. 0). I'm just getting started with PIC, so please forgive my ignorance. Thanks for any help you can give.
Mac
The command line is:
sdcc -mpic14 -p16f628 SDCC_Test.c
Here is the C code:
#define __16f628
#include "pic/pic16f628.h"
// Set the __CONFIG word:
typedef unsigned int word;
word at 0x2007 __CONFIG = 0x3D90;
void main(void)
{
/* unsigned char count0; */
unsigned char count1;
unsigned char count2;
TRISA = 0;
/* count0 = 0x01; */
while(1) {
PORTA = 0;
count1 = 0x7f;
while(count1 != 0) {
count2 = 0xff;
while (count2 != 0) {
count2--;
}
count1--;
}
PORTA = 1;
count1 = 0x7f;
while(count1 != 0) {
count2 = 0xff;
while (count2 != 0) {
count2--;
}
count1--;
}
/* count0--; */
}
}
This is (what I think is) the relevant part of the assembly that is generated:
;--------------------------------------------------------
; udata
;--------------------------------------------------------
data_SDCC_Test udata
; .area DSEG (DATA)
udata_SDCC_Test_0 udata
r0x20 res 1
udata_SDCC_Test_1 udata
r0x21 res 1
;--------------------------------------------------------
; overlayable items in internal ram
;--------------------------------------------------------
; udata_ovr
;--------------------------------------------------------
; bit data
;--------------------------------------------------------
; .area BSEG (BIT)
;--------------------------------------------------------
; reset vector
;--------------------------------------------------------
STARTUP code
nop
pagesel __sdcc_gsinit_startup
goto __sdcc_gsinit_startup
code_init code
__sdcc_gsinit_startup
pagesel _main
goto _main
;--------------------------------------------------------
; code
;--------------------------------------------------------
code_SDCC_Test code
;***
; pBlock Stats: dbName = M
;***
;entry: _main ;Function start
; 2 exit points
;has an exit
;2 compiler assigned registers:
; r0x20
; r0x21
;; Starting pCode block
_main ;Function start
; 2 exit points
; .line 16; "SDCC_Test.c" TRISA = 0;
BSF STATUS,5
BCF STATUS,6
CLRF _TRISA
_00118_DS_
; .line 19; "SDCC_Test.c" PORTA = 0;
BCF STATUS,5
CLRF _PORTA
; .line 21; "SDCC_Test.c" while(count1 != 0) {
MOVLW 0x7f
BANKSEL r0x20
MOVWF r0x20
_00108_DS_
MOVF r0x20,W
BTFSS STATUS,2
GOTO _00134_DS_
GOTO _00110_DS_
_00134_DS_
; .line 23; "SDCC_Test.c" while (count2 != 0) {
MOVLW 0xff
MOVWF r0x21
_00105_DS_
MOVF r0x21,W
BTFSS STATUS,2
GOTO _00135_DS_
GOTO _00107_DS_
_00135_DS_
; .line 24; "SDCC_Test.c" count2--;
DECF r0x21,F
GOTO _00105_DS_
_00107_DS_
; .line 26; "SDCC_Test.c" count1--;
DECF r0x20,F
GOTO _00108_DS_
_00110_DS_
; .line 28; "SDCC_Test.c" PORTA = 1;
MOVLW 0x01
BCF STATUS,5
BCF STATUS,6
MOVWF _PORTA
; .line 30; "SDCC_Test.c" while(count1 != 0) {
MOVLW 0x7f
BANKSEL r0x20
MOVWF r0x20
_00114_DS_
MOVF r0x20,W
BTFSS STATUS,2
GOTO _00136_DS_
GOTO _00118_DS_
_00136_DS_
; .line 32; "SDCC_Test.c" while (count2 != 0) {
MOVLW 0xff
MOVWF r0x21
_00111_DS_
MOVF r0x21,W
BTFSS STATUS,2
GOTO _00137_DS_
GOTO _00113_DS_
_00137_DS_
; .line 33; "SDCC_Test.c" count2--;
DECF r0x21,F
GOTO _00111_DS_
_00113_DS_
; .line 35; "SDCC_Test.c" count1--;
DECF r0x20,F
GOTO _00114_DS_
RETURN
; exit point of _main
; code size estimation:
; 42+ 2 = 44 instructions ( 92 byte)
end
After quite a few hours of study and learning about how PICs and SDCC work, I found that the problem is not a missing while(1) loop. It actually appears to be related to bug report 1570934 (BANKSEL missing). A fix has been put in place (r4409) to solve the problem. I will investigate this further and post an additional bug report if necessary.
Mac