Menu

Endless loop dropped by SDCC 2.6.0 for PIC14

Help
Mac Cody
2006-10-15
2013-03-12
  • Mac Cody

    Mac Cody - 2006-10-15

    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

     
    • Mac Cody

      Mac Cody - 2006-10-15

      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

       
    • Mac Cody

      Mac Cody - 2006-10-15

      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

       

Log in to post a comment.