Hot!Debug VS Production mode - different behaviour

Author
Maldus
Starting Member
  • Total Posts : 47
  • Reward points : 0
  • Joined: 2016/08/17 09:55:57
  • Location: 0
  • Status: offline
2018/05/06 00:07:24 (permalink)
0

Debug VS Production mode - different behaviour

Hello everyone,
I'm working on a project using a PIC24FJ256GA704.  The device I'm programming has a couple of GPIO and, most importantly, an SPI-controlled display. I have a simple graphic library to write text on a framebuffer that I then periodically send to the display.
 
I was having some difficulties working with it until I realized it was displaying a significantly different behaviour between Debug mode and Device mode (Program). Long story short, when in Debug mode everything works as expected, while in Device mode:
   - Interrupt priority is seemingly not respected: I have a 100us timer interrupt (on timer3) that sometimes doesn't fire, apparently due to a longer function being executed from timer1 (the display refresh), despite the latter having a lower priority.
   - The characters on the display are gibberish (random strings instead of what should be displayed).
 
What I really can't wrap my head around is the fact that the second problem (gibberish strings on display) can be resolved apparently by adding/removing a certain number of register accesses in interrupt code. This is my timer3 interrupt routine:
 

/*----------------------------------------------------------------------------*/
/*  Timer Interrupt 3 - 100 usec                                              */
/*----------------------------------------------------------------------------*/
void __attribute__((interrupt, auto_psv)) _T3Interrupt (void)       
{
    static int     triac_on_time = 0;
    
    
    if (f_pwm_on)
    {
        if (pwm_off_time > 0)
        {
            TRIAC = 0;
            pwm_off_time--;
            
            if (pwm_off_time == 0)
            {
                triac_on_time = 3;
                TRIAC = 1;
                IEC0bits.T1IE = 0;
                IEC0bits.T2IE = 0;
            }

//            LED_RUN = LED_RUN;
//            LED_RUN = LED_RUN;
//            LED_RUN = LED_RUN;

        }
        else if (triac_on_time > 0)
        {
            triac_on_time--;
            
            if (triac_on_time == 0)
            {
                TRIAC = 0;
                IEC0bits.T1IE = 1;
                IEC0bits.T2IE = 1;
            }
                
        }
    }
    else
    {
        TRIAC = 0;
        IEC0bits.T1IE = 1;
        IEC0bits.T2IE = 1;
    }

    IFS0bits.T3IF = 0;
}

 
LED_RUN is a macro defined as LATBbits.LATB8 (a small LED used for testing purposes). Depending on how many of the commented out lines I leave in the code, in Program/Device mode, the following happens:
   - 0 lines: everything works as expected
   - 1 line: the screen is empty and the device unresponsive
   - 2 lines: the strings are gibberish and the device becomes unresponsive after using it for a while (possibly ending up in an address error or similar, can't really tell because this beaviour does not occur in Debug mode).
   - 3 lines: similar results, ...
 
 
From what I can see it appears the code size is somehow messing with the fonts, that are defined as const char arrays. However, again, this does not occur in Debug mode, and both .map files seem fine (Debug and Production .map file have the same addresses for .const sections).
 
I realize the problem is vaguely described, but I don't know what to do at this point. My questions are:
   1. Did anyone stumble in a similar problem before?
   2. What information do you think would be useful to better understand my problem and/or fix it?
 
If it can be of any help, those are my configuration bits. I'm running at 16MHz (FOSC) with the internal FRC+PLL.
 

/* FSEC */
#pragma config BWRP = OFF               /* Boot Segment Write-Protect bit (Boot Segment may be written) */
#pragma config BSS = DISABLED           /* Boot Segment Code-Protect Level bits (No Protection (other than BWRP)) */
#pragma config BSEN = OFF               /* Boot Segment Control bit (No Boot Segment) */
#pragma config GWRP = OFF               /* General Segment Write-Protect bit (General Segment may be written) */
#pragma config GSS = DISABLED           /* General Segment Code-Protect Level bits (No Protection (other than GWRP)) */
#pragma config CWRP = OFF               /* Configuration Segment Write-Protect bit (Configuration Segment may be written) */
#pragma config CSS = DISABLED           /* Configuration Segment Code-Protect Level bits (No Protection (other than CWRP)) */
#pragma config AIVTDIS = OFF            /* Alternate Interrupt Vector Table bit (Disabled AIVT) */

/* FBSLIM */
#pragma config BSLIM = 0x1FFF           /* Boot Segment Flash Page Address Limit bits (Boot Segment Flash page address  limit) */

/* FSIGN */

/* FOSCSEL */
#pragma config FNOSC = FRCPLL//OSCFDIV              /* Oscillator Source Selection (Internal Fast RC (FRC)) */
#pragma config PLLMODE = 0b0001//DISABLED       /* PLL Mode Selection (No PLL used; PLLEN bit is not available) */
#pragma config IESO = OFF               /* Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source) */

/* FOSC */
#pragma config POSCMD = NONE              /* Primary Oscillator Mode Select bits (XT Crystal Oscillator Mode) */
#pragma config OSCIOFCN = ON           /* OSC2 Pin Function bit (OSC2 is a General Purpose IO) */
#pragma config SOSCSEL = OFF             /* Digital mode */
#pragma config PLLSS = PLL_FRC          /* PLL Secondary Selection Configuration bit (PLL is fed by the on-chip Fast RC (FRC) oscillator) */
#pragma config IOL1WAY = OFF            /* Peripheral pin select configuration bit (Allow multiple reconfigurations) */
#pragma config FCKSM = CSECMD           /* Clock Switching Mode bits (Clock switching is enabled,Fail-safe Clock Monitor is disabled) */

/* FWDT */
#pragma config WDTPS = PS32768          /* Watchdog Timer Postscaler bits (1:32,768) */
#pragma config FWPSA = PR128            /* Watchdog Timer Prescaler bit (1:128) */
#pragma config FWDTEN = OFF             /* Watchdog Timer Enable bits (WDT and SWDTEN disabled) */
#pragma config WINDIS = OFF             /* Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode) */
#pragma config WDTWIN = WIN25           /* Watchdog Timer Window Select bits (WDT Window is 25% of WDT period) */
#pragma config WDTCMX = WDTCLK          /* WDT MUX Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits) */
#pragma config WDTCLK = LPRC            /* WDT Clock Source Select bits (WDT uses LPRC) */

/* FPOR */
#pragma config BOREN = ON               /* Brown Out Enable bit (Brown Out Enable Bit) */
#pragma config LPCFG = OFF              /* Low power regulator control (No Retention Sleep) */
#pragma config DNVPEN = ENABLE          /* Downside Voltage Protection Enable bit (Downside protection enabled using ZPBOR when BOR is inactive) */

/* FICD */
#pragma config ICS = PGD2               /* ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1) */
#pragma config JTAGEN = OFF             /* JTAG Enable bit (JTAG is disabled) */

/* FDEVOPT1 */
#pragma config ALTCMPI = DISABLE        /* Alternate Comparator Input Enable bit (C1INC, C2INC, and C3INC are on their standard pin locations) */
#pragma config TMPRPIN = OFF            /* Tamper Pin Enable bit (TMPRN pin function is disabled) */
#pragma config SOSCHP = ON              /* SOSC High Power Enable bit (valid only when SOSCSEL = 1 (Enable SOSC high power mode (default)) */
#pragma config ALTI2C1 = ALTI2CDIS       /* Alternate I2C pin Location (SDA1 and SCL1 on RB9 and RB8) */



#1

10 Replies Related Threads

    aschen0866
    Super Member
    • Total Posts : 4356
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/06 08:11:50 (permalink)
    0
    Do both builds, debug vs. production, have the same level of optimization? Anything in your code that manipulates the PSVPAG register? Any definitions that use __attribute__ or #pragma? Custom linker script? Conditional compilation based upon __DEBUG? 
     
    What anyone needs is a simple project that demonstrates this issue.
    #2
    Maldus
    Starting Member
    • Total Posts : 47
    • Reward points : 0
    • Joined: 2016/08/17 09:55:57
    • Location: 0
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/06 08:41:58 (permalink)
    0
    aschen0866Do both builds, debug vs. production, have the same level of optimization?

    Is it even possible to have different options? I only use a single configuration, and the optimization level is 0
     
    aschen0866Anything in your code that manipulates the PSVPAG register?

    Not directly. I had some strings stored esplicitly in the PSV section, but I redefined them as const while looking for a solution.
     
    aschen0866Any definitions that use __attribute__ or #pragma?

    My interrupts have __attribute__((interrupt, auto_psv)), and some of that code manipulates the strings that end up scrambled on the display, so it might be worth trying to move it somewhere else and see what changes.
     
     
    aschen0866Custom linker script? Conditional compilation based upon __DEBUG?

    Nothing of the sort.
     
    aschen0866What anyone needs is a simple project that demonstrates this issue.

    Yes, I understand. It's just not easy to pinpoint the problem and reproduce it with a simple example; I'll keep trying.
    Even after a vague description, your questions are already helpful.


    #3
    RISC
    Super Member
    • Total Posts : 5359
    • Reward points : 0
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/06 10:44:14 (permalink)
    0
    Hi,
    Debug and release mode are similar except very few points :
    * In debug mode , watchdog is automatically disables as well as code protection.
    * The tool generally add an interna pull-up on MCLR (if you disconnect your board it may exhibit a different behaviour depending upon your external reset circuitry
    * it may happen that a couple of GPIOs are initialized in debug mode 
     
    So if your software does not run or run strangely in release mode you have most probably missed some initialization
    ( NB : i suppoed you did not attach any external signals to PGC / PGD pins on your hardware)
     
    Any unused input pin MUST either be initialized as output or polarised externally otherwise you'll get noise into the PIC which may exhibit any strange behaviour
     
    Regards
    #4
    JackG
    Starting Member
    • Total Posts : 39
    • Reward points : 0
    • Joined: 2011/05/06 08:09:43
    • Location: Vermont, USA
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/06 19:22:31 (permalink)
    0
    Are you refreshing the display within timer1 interrupt or just setting a flag and refreshing in the main loop?
    If the former, try the latter.
    post edited by JackG - 2018/05/06 19:26:05
    #5
    Aussie Susan
    Super Member
    • Total Posts : 3364
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/06 19:39:13 (permalink)
    5 (1)
    As well as the differences that RISC mentions, others are:
    - in debug mode, a small 'debug kernel' is loaded in with your code that communicates with the debugger in the IDE
    - that debug kernel uses the PGCx/PGDx pair to communicate with the debugger so you cannot use them for anything in your code
    - the debug kernel also initialises the 'analog/digital' mode for pins that have an analog function to 'digital' where as they otherwise initialise to 'analog'
    - when you do a reset, the debug kernel takes control and waits for some interaction with the debugger, whereas you code starts on reset in 'release' mode
    - if you use the watch window or otherwise to look at various peripheral registers, you can get misleading results (especially any register that provides the results of a FIFO)
    The bottom line is that you really should initialise everything that you use.
    Susan
    #6
    Maldus
    Starting Member
    • Total Posts : 47
    • Reward points : 0
    • Joined: 2016/08/17 09:55:57
    • Location: 0
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/07 00:15:28 (permalink)
    0
    RISC
    ( NB : i suppoed you did not attach any external signals to PGC / PGD pins on your hardware)
     
    Any unused input pin MUST either be initialized as output or polarised externally otherwise you'll get noise into the PIC which may exhibit any strange behaviour

    You suppose right. Also all the unused pins are initialized as output and driven to 0.
     
    JackG
    Are you refreshing the display within timer1 interrupt or just setting a flag and refreshing in the main loop?
    If the former, try the latter.

    Tried both, apparently no difference (though I should check properly if the timer3 really skips sometimes in both cases, will do in the next days).
     
    Aussie Susan
    The bottom line is that you really should initialise everything that you use.

    I think I have, but I'll double check. In the next days we will try the same program & device with a different (albeit very similar) PIC, because we really need to get this job done. If by luck it works I'll keep trying to understand what the problem was in my spare time, otherwise I'll need to pinpoint the problem with a reproducible example.
    #7
    Maldus
    Starting Member
    • Total Posts : 47
    • Reward points : 0
    • Joined: 2016/08/17 09:55:57
    • Location: 0
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/10 01:59:37 (permalink)
    0
    Update
    So we tried using a PIC24EP256GP204 instead of the PIC24FJ256GA704; it has a very similar pinout and specs, and we already worked succesfully with it.
    Long story short the difference between Debug and Production mode simply disappeared. The circuit and program are the same (save for some registers that have different names).
     
    We still have some problems with interrupt timers, but I believe that to be a separate issue. Maybe one day I'll come back to the original PIC and try to assemble a reproducible example, but for now we have more pressing matters to attend to.
     
    Thanks to everyone who tried to help with suggestions.
    #8
    RISC
    Super Member
    • Total Posts : 5359
    • Reward points : 0
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/10 02:00:51 (permalink)
    0
    Hi,
    A few more points to think about...
    Did you (or not) enable interrupt priority ?
    I noticed you manipulate in T1 interrupt other interrupts enable/disable bits but we don't know what is their priority.
    Also the succession of enable/disable T2 and T3 is not atomic. Could this potentially generate an issue
     
    My point is : manipulating other interrupts enable/disable bits from within an interrupt is often a source of issues... Make sure that either T1 has a higher priority or do it in the main routine.
    another way is having all interrupts with the same priority
    Regards
     
     
    #9
    Maldus
    Starting Member
    • Total Posts : 47
    • Reward points : 0
    • Joined: 2016/08/17 09:55:57
    • Location: 0
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/05/11 05:57:13 (permalink)
    0
    RISC
    Did you (or not) enable interrupt priority ?

     
    I enabled it and tried several different combinations. However I don't really want to discuss this here because I believe it to be a separate issue, deserving another thread (that I will most likely create soon). The differences between Debug and Production mode persist even after disabling all interrupts.
    #10
    Maldus
    Starting Member
    • Total Posts : 47
    • Reward points : 0
    • Joined: 2016/08/17 09:55:57
    • Location: 0
    • Status: offline
    Re: Debug VS Production mode - different behaviour 2018/06/13 06:50:46 (permalink)
    0
    I seem to have found a workaround. I kept having several unexplicable problems until I noticed the gcc settings for the memory model were all set to [default] (Project properties -> xc16-gcc -> Memory model).
     
    All the unwanted behaviours (varibles not changing their values, address errors, ...) that were happening in Release mode but not in Debug disappeared when I set the memory model to "large" for data, scalar and code.
     
    I thought the compiler (the linker) was supposed to throw an error if my code grew too much and required large models to run. I don't have the time to find a more precise description of the problem and/or the solution.
    #11
    Jump to:
    © 2018 APG vNext Commercial Version 4.5