Menu

#2721 bool:1 bitfield always evaluates to true

open
nobody
None
PIC16
5
2018-03-01
2018-02-19
No

Background:

I am an ECET student programming a PIC from MPLAB X using the SDCC plugin. My system is a Debian Stretch. I recently manually installed SDCC and GPUTILS. In my application, I have a PIC18F2520 with an LED on PORTC bit 1 and a button on PORTA bit 3.

Expected Behavior:

LED changes state every ~0.5s. Pressing the button will toggle the state of the LED.

Observed Behavior:

  1. LED is stuck on. Pressing the button has no effect.
  2. Commenting LedToggle() in void loop() (main.c:120) will produce a program which does not blink the LED, but it may be toggled using the button.
  3. Commenting all calls to Timer.c in main.c produces the same effect as (2).
  4. When compiled using Microchip's (rather wanting) XC8 on free license, the program works correctly. (but I would much rather not use that piece of "work")

Version:

sdcc -v
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.7.0 #10228 (Linux)

Build Process:

I am not 100% sure how the SDCC plugin works together with MPLAB X to compile my project, but I have attached the entire project here in case it is useful. Here is the text output of the build window:

CLEAN SUCCESSFUL (total time: 60ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory '/media/data/peterl/Source/MPLabX/Timer.X'
make  -f nbproject/Makefile-default.mk dist/default/production/Timer.X.production.hex
make[2]: Entering directory '/media/data/peterl/Source/MPLabX/Timer.X'
mkdir -p "build/default/production" 
mkdir -p "build/default/production" 
mkdir -p "build/default/production" 
mkdir -p "build/default/production" 
rm -f  build/default/production/Led.o 
"/usr/local/bin/sdcc" --use-non-free --opt-code-size -c -mpic16 -p18f2520 Led.c  -obuild/default/production/Led.o
rm -f  build/default/production/main.o 
rm -f  build/default/production/Timer.o 
"/usr/local/bin/sdcc" --use-non-free --opt-code-size -c -mpic16 -p18f2520 main.c  -obuild/default/production/main.o
rm -f  build/default/production/Button.o 
"/usr/local/bin/sdcc" --use-non-free --opt-code-size -c -mpic16 -p18f2520 Timer.c  -obuild/default/production/Timer.o
"/usr/local/bin/sdcc" --use-non-free --opt-code-size -c -mpic16 -p18f2520 Button.c  -obuild/default/production/Button.o
mkdir -p dist/default/production 
"/usr/local/bin/sdcc" -Wl-c -Wl-m --use-non-free --opt-code-size -mpic16 -p18f2520 build/default/production/Timer.o build/default/production/main.o build/default/production/Led.o build/default/production/Button.o -odist/default/production/Timer.X.production.hex 
message: Using default linker script "/usr/local/share/gputils/lkr/18f2520_g.lkr".
warning: Relocation symbol "_cinit" [0x00001C] has no section. (pass 0)
warning: Relocation symbol "_cinit" [0x000020] has no section. (pass 0)
warning: Relocation symbol "_cinit" [0x000024] has no section. (pass 0)
warning: Relocation symbol "_cinit" [0x00001C] has no section. (pass 0)
warning: Relocation symbol "_cinit" [0x000020] has no section. (pass 0)
warning: Relocation symbol "_cinit" [0x000024] has no section. (pass 0)
make[2]: Leaving directory '/media/data/peterl/Source/MPLabX/Timer.X'
make[1]: Leaving directory '/media/data/peterl/Source/MPLabX/Timer.X'

BUILD SUCCESSFUL (total time: 569ms)

P.S.

As I have no idea as to the cause of this behavior, I have not really come up with a simpler case than the code provided. However, I will try to the best of my knowledge to help out in whatever way I can. This is my first (ever!) bug report, please go easy on me! ;)

1 Attachments

Discussion

  • Peter Lapets

    Peter Lapets - 2018-02-19

    Clarification. (3) is in addition to (2).

     
  • Maarten Brock

    Maarten Brock - 2018-02-19

    Have you looked at the LED with an oscilloscope? I bet it's blinking too fast for your eyes to see.

     
    • Peter Lapets

      Peter Lapets - 2018-02-19

      I can't believe that didn't occur to me. You're absolutely right. Now to find out why...

       

      Last edit: Peter Lapets 2018-02-19
  • Peter Lapets

    Peter Lapets - 2018-02-19

    The oscilloscope shows a 44.36 uS duration between LED toggles. On a system oscillator of 32 MHz, /4 for 8 MHz, this yields ~355 cycles. These pulses are periodically longer due to an interrupt call. This is not such a long time, and my guess would be that a flag in my code is stuck TRUE for some reason and the main loop code keeps running without interruption. What gives me pause is that the same code runs on XC8 without issue. If there's a compiler quirk I'm overlooking, I'd greatly appreciate a few pointers.

     
  • Peter Lapets

    Peter Lapets - 2018-02-21

    I've found the source of the problem. In my code, I have a typedef struct:

    typedef struct TimerEntry
    {
        timer_event_t   eventType   : 4;
        timer_state_t   state       : 1;
        bool            flag        : 1;
    
        timer_value_t   period,
                        count;
    } TimerEntry;
    

    In another part of the code, I have the following function:

    bool TimerFlagRaised(timer_handle_t timer)
    {
        return (g_timerEntries[timer].flag);
    }
    

    This always returns true. However, if I change it to:

    bool TimerFlagRaised(timer_handle_t timer)
    {
        return (g_timerEntries[timer].flag == true);
    }
    

    then everything works as expected.

    ...that shouldn't do that, should it?

     

    Last edit: Peter Lapets 2018-02-21
  • Maarten Brock

    Maarten Brock - 2018-02-22

    Can you show the generated assembly for these two cases?

     
  • Peter Lapets

    Peter Lapets - 2018-03-01

    I apologize for the delay -- for some reason my email put everything into spam folder.
    n.b. this assembly is from invocation with no optimization.

    Working case:

    ; I code from now on!
    ; ; Starting pCode block
    S_Timer__TimerFlagRaised    code
    _TimerFlagRaised:
    ;   .line   126; Timer.c    bool TimerFlagRaised(timer_handle_t timer)
        MOVFF   FSR2L, POSTDEC1
        MOVFF   FSR1L, FSR2L
        MOVFF   r0x00, POSTDEC1
        MOVFF   r0x01, POSTDEC1
        MOVLW   0x02
        MOVFF   PLUSW2, r0x00
    ; ;multiply lit val:0x05 by variable r0x00 and store in r0x00
    ;   .line   129; Timer.c    return (g_timerEntries[timer].flag == true);
        MOVF    r0x00, W
        MULLW   0x05
        MOVF    PRODH, W
        BTFSC   r0x00, 7
        SUBLW   0x05
        MOVWF   r0x01
        MOVFF   PRODL, r0x00
        MOVLW   LOW(_g_timerEntries)
        ADDWF   r0x00, F
        MOVLW   HIGH(_g_timerEntries)
        ADDWFC  r0x01, F
        CLRF    WREG
        MOVFF   r0x00, FSR0L
        MOVFF   r0x01, FSR0H
        BTFSC   INDF0, 5
        INCF    WREG, F
        MOVWF   r0x00
        MOVF    r0x00, W
        XORLW   0x01
        BNZ _00227_DS_
        CLRF    r0x00
        INCF    r0x00, F
        BRA _00228_DS_
    _00227_DS_:
        CLRF    r0x00
    _00228_DS_:
        MOVF    r0x00, W
    ;   .line   133; Timer.c    }
        MOVFF   PREINC1, r0x01
        MOVFF   PREINC1, r0x00
        MOVFF   PREINC1, FSR2L
        RETURN  
    

    Non-working case:

    ; I code from now on!
    ; ; Starting pCode block
    S_Timer__TimerFlagRaised    code
    _TimerFlagRaised:
    ;   .line   126; Timer.c    bool TimerFlagRaised(timer_handle_t timer)
        MOVFF   FSR2L, POSTDEC1
        MOVFF   FSR1L, FSR2L
        MOVFF   r0x00, POSTDEC1
        MOVFF   r0x01, POSTDEC1
        MOVLW   0x02
        MOVFF   PLUSW2, r0x00
    ; ;multiply lit val:0x05 by variable r0x00 and store in r0x00
    ;   .line   131; Timer.c    return (g_timerEntries[timer].flag);
        MOVF    r0x00, W
        MULLW   0x05
        MOVF    PRODH, W
        BTFSC   r0x00, 7
        SUBLW   0x05
        MOVWF   r0x01
        MOVFF   PRODL, r0x00
        MOVLW   LOW(_g_timerEntries)
        ADDWF   r0x00, F
        MOVLW   HIGH(_g_timerEntries)
        ADDWFC  r0x01, F
        CLRF    WREG
        MOVFF   r0x00, FSR0L
        MOVFF   r0x01, FSR0H
        BTFSC   INDF0, 5
        INCF    WREG, F
        MOVWF   r0x00
        MOVF    r0x00, W
        BTFSC   STATUS, 2
        MOVLW   0x01
        MOVWF   r0x00
        MOVF    r0x00, W
    ;   .line   133; Timer.c    }
        MOVFF   PREINC1, r0x01
        MOVFF   PREINC1, r0x00
        MOVFF   PREINC1, FSR2L
        RETURN  
    
     

    Last edit: Peter Lapets 2018-03-01
  • Maarten Brock

    Maarten Brock - 2018-03-01
    • summary: Program compiles without errors, but MCU appears to hang --> bool:1 bitfield always evaluates to true
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,4 +1,3 @@
    -
     ### Background:
     I am an ECET student programming a PIC from MPLAB X using the SDCC plugin.  My system is a Debian Stretch.  I recently manually installed SDCC and GPUTILS.  In my application, I have a PIC18F2520 with an LED on PORTC bit 1 and a button on PORTA bit 3.
    
     
  • Maarten Brock

    Maarten Brock - 2018-03-01

    Changed subject on OP's request

     

Log in to post a comment.

Monday.com Logo