#2058 #pragma config and certain string constants

closed-fixed
Borut Ražem
5
2013-06-21
2012-07-03
Herbert Pötzl
No

when combining (implicit?) string constants and #pragma config, the strings end up right after the CONFIG directives which leads to the following error and warning:

$ sdcc --use-non-free -mpic16 -p18f26j50 config_bug.c
config_bug.asm:485:Error[152] Executable code and data must be defined in an appropriate section.
config_bug.asm:485:Warning[220] Address exceeds maximum range for this processor.
...

$ sdcc -v
SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08 3.2.0 #7999 (Jul 3 2012) (Linux)

$ gpasm -v
gpasm-0.14.2 #711 (Jul 3 2012)

from config_bug.asm:
; ; Starting pCode block
CONFIG WDTEN=OFF
; ; Starting pCode block
__str_0:
DB 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00

note: it might as well be a gputils issue but I presume that 'CONFIG' simply advances to the defined addresses and thus the following string ends up _after_ the config space which of course is bogus.

Discussion

  • Herbert Pötzl
    Herbert Pötzl
    2012-07-03

    example code exposing the issue

     
    Attachments
  • Herbert Pötzl
    Herbert Pötzl
    2012-07-03

    ugly hack to paper over the issue

     
  • Herbert Pötzl
    Herbert Pötzl
    2012-07-03

    IMHO the best approach would be to move all the CONFIG directives to the beginning before any actual code is generated (tried that with a new 'config' Map but that didn't work and I'm lost in the sdcc source code :)

     
  • Borut Ražem
    Borut Ražem
    2012-07-06

    • assigned_to: nobody --> borutr
    • status: open --> open-fixed
     
  • Borut Ražem
    Borut Ražem
    2012-07-06

    Patch sdcc-3.2.0-config_fix.diff applied in svn revision #8008, since it is pic16 specific, it doesn't affect other targets and it is low risk.

    The more appropriate 'config' Map approach can be implemented after the SDCC 3.2.0 release, so I'm leaving this bug opened.

    Borut

     
  • Diego Herranz
    Diego Herranz
    2012-07-10

    IMHO, I think this bug isn't fixed.

    If you modify config_bug.c adding another pragma config like:

    #pragma config WDTPS = 1

    You see this error again:
    $ sdcc --use-non-free -mpic16 -p18f26j50 config_bug.c
    config_bug.asm:487:Error[152] Executable code and data must be defined in an appropriate section.
    [...]

    Useful data:

    $ sdcc -v
    SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08 3.2.0 #8008 (Jul 6 2012) (Linux)

    $ gpasm -v
    gpasm-0.14.2 #711 (Jul 9 2012)

     
  • Borut Ražem
    Borut Ražem
    2012-07-10

    > IMHO, I think this bug isn't fixed.

    Unfortunately this is true. But it was never stated as fixed in an appropriate way, only a temporary patch was applied to make pic18 usable and the bug was not closed.

    Workaround for the problem with several #pragma configs is to use a single "all in one" #pragma config.

    For example instead using:

    #pragma config EBTRB=OFF
    #pragma config EBTR3=OFF
    #pragma config EBTR2=OFF
    #pragma config EBTR1=OFF

    you can use:

    #pragma config EBTRB=OFF, EBTR3=OFF, EBTR2=OFF, EBTR1=OFF

    Borut

     
  • Borut Ražem
    Borut Ražem
    2012-07-10

    • status: open-fixed --> open
     
  • Borut Ražem
    Borut Ražem
    2012-07-10

    Sorry Diego, you are right, the bug "Status" was still "Open", but "Resolution" was "Fixed". Now I changed the "Resolution" back to "None".

    Borut

     
  • Diego Herranz
    Diego Herranz
    2012-07-10

    I'll use the one line pragma as a temporary workaround. Thanks.

    Anyway, I still don't know why I had no errors with 3.2 RC3 (#7999). Maybe it depends on the place where the pragmas are located or... don't know.

    In fact, using 3.2 RC3 (#7999) with 18f4550 and multiline pragmas I get the following asm file which seems to be correct (doesn't it?):

    [...]
    CONFIG PWRT=ON
    ; ; Starting pCode block
    CONFIG IESO=OFF
    ; ; Starting pCode block
    CONFIG FCMEN=OFF
    ; ; Starting pCode block
    CONFIG FOSC=HSPLL_HS
    ; ; Starting pCode block
    CONFIG USBDIV=2
    ; ; Starting pCode block
    CONFIG CPUDIV=OSC1_PLL2
    ; ; Starting pCode block
    CONFIG PLLDIV=1
    ; ; Starting pCode block for Ival
    [...] code

    and some arrays and strings after that.

    Thanks a lot.

     
  • Borut Ražem
    Borut Ražem
    2012-07-10

    > I'll use the one line pragma as a temporary workaround. Thanks.

    I'm glat that it works for you.

    > Anyway, I still don't know why I had no errors with 3.2 RC3 (#7999). Maybe
    > it depends on the place where the pragmas are located or... don't know.

    Build #7999 has a problem when a constant string is defined in a function. See the config_bug.c attachment. That's why the patch was applied in build #8008, which fixed the "constant string defined in a function" problem by switching to "code" section after emitting the CONFIG directive. But unfortunately it introduced the "multiple #pragma configs" one, since the "code" directive is emitted after each CONFIG directive.

    > In fact, using 3.2 RC3 (#7999) with 18f4550 and multiline pragmas I get the
    > following asm file which seems to be correct (doesn't it?):

    Yes, it seems correct. Can you please attach the c source, so that I can analyze it?

    Borut

     
  • Diego Herranz
    Diego Herranz
    2012-07-11

    This is a small example where using #7999, code is generated correctly. However, if fooarray line is commented, errors like these are found:

    main.asm:348:Warning[220] Address exceeds maximum range for this processor.
    main.asm:348:Error[152] Executable code and data must be defined in an appropr

    main.c file (can't attach a file):

    #include <pic18fregs.h>

    const int fooarray[5] ={0x00, 0x00, 0x00, 0x00, 0x00};

    #pragma config CP0 = ON
    #pragma config CP1 = ON
    #pragma config CP2 = ON
    #pragma config CP3 = ON

    //Foo function
    void foo(const char *str){
    }

    void main (void){

    foo("hello");

    }

    sdcc command:
    $ sdcc --use-non-free -mpic16 -p18f4550 main.c

    $ sdcc -v
    SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08 3.2.0 #7999 (Jun 29 2012) (Linux)

     
  • Diego Herranz
    Diego Herranz
    2012-07-11

    Forgot to say,

    Thanks a lot!

     
  • Borut Ražem
    Borut Ražem
    2012-07-12

    Diego,

    the source code snippet compiles OK wth revision #7999 since the code for array fooarray[] is generated before the constant string "hello" and the array genertes "code" directive by itself.

    Unfortunately this example doesn't work with sdcc revision #8008 (SDCC 3.2.0), even if "all in one" #pragna directive is used, since there are two "code" directives generated: one from #pragnma config and the second from fooarray[]. Gpasm complains with: "main.asm:78:Error[154] Each object file section must be contiguous." :-(

    Borut

     
  • Borut Ražem
    Borut Ražem
    2012-07-12

    • milestone: --> fixed
    • status: open --> closed-fixed
     
  • Borut Ražem
    Borut Ražem
    2012-07-12

    Properly fixed (hopefully) in svn revision #8038.

    Any report from users is welcome.

    Borut

     
  • Diego Herranz
    Diego Herranz
    2012-07-12

    Great!

    I'll test it tomorrow when snapshot is built. Is it supposed to work also with multi-line pragma CONFIG?

    Thank you very much

     
  • Borut Ražem
    Borut Ražem
    2012-07-12

    > it supposed to work also with multi-line pragma CONFIG?

    Yes.

    Borut

     
  • Diego Herranz
    Diego Herranz
    2012-07-14

    I've tested it and it seems to work like a charm.

    Thanks again!

     
  • Hi i have the same problem with

    [miguel@dhcppc6 ~]$ sdcc -v
    SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08 3.2.0 #8008 (Jul 27 2012) (Linux)
    

    in Fedora 18 64 bits compiling a program with Piklab 0.16
    The error is:

    sdcc --use-non-free -mpic16 -p18f2550 -V --debug -I/home/miguel/Documentos/ITST2013A/Proyectos2013/IGLFinal/ -c MainExpociencias.c 
    MainExpociencias.asm:4466: error: CONFIG Directive Error: (setting not found for selected processor) 
    MainExpociencias.asm:4468: error: Each object file section must be contiguous (section .code) 
    MainExpociencias.asm:4470: error: Each object file section must be contiguous (section .code)
    

    when i use this coding

    #include <pic18f2550.h>
    #pragma config FOSC = HSPLL_HS, PLLDIV=5, CPU_DIV = OSC1_PLL2, USBDIV = 2
    #pragma config IESO = ON
    
    #define FOSC 48000000
    #include "simple_delay.h"
    #include "fLCD3bSDCC.h"
    #include "cabecera.h"
    

    and the code in asm generated is:

    ; ; Starting pCode block
        CONFIG  IESO=ON
        code
    ; ; Starting pCode block
        CONFIG  FOSC=HSPLL_HS,PLLDIV=5,CPU_DIV=OSC1_PLL2,USBDIV=2
        code
    ; ; Starting pCode block for Ival
        code
    _LCD_INIT_STRING:
        DB  0x28, 0x01, 0x0c, 0x06, 0x0c
    ; ; Starting pCode block
    __str_0:
        DB  0x20, 0x20, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x73, 0x6d
        DB  0x6f, 0x20, 0x70, 0x61, 0x72, 0x61, 0x20, 0x20, 0x00
    

    This problem start when my system was updated, before that the problem don't exist. and now with this configuration the error is

    sdcc --use-non-free -mpic16 -p18f2550 -V --debug -Wl-c -Wl-m -I/home/miguel/Documentos/ITST2013A/Proyectos2013/IGLFinal/ libc18f.lib -oiglMontiel.hex MainExpociencias.o 
    using default linker script "/usr/share/gputils/lkr/18f2550_g.lkr" 
    section ".config_300000_MAINEXPOCIENCIAS.O" is absolute but occurs in more than one file
    

    when my code is

    /** 
     * @File:   newmain.c
     * @Author: Miguel Montiel Martínez
     * @brief
     * Programa para el control de un dispositivo de automatización en mediciones
     * de susceptibilidad magnética en investigación paleo-ambiental a cargo del PhD Priyadarsi Debajyoti Roy
     * 
     * @verbatim
     * 16/05/2012  Actualizacion
     * son creadas las rutinas para elegir una entre tres velocidades sugeridas por el usuario
     * Se determina el numero de microsegundos que son necesarios para que los motores de paso tengan esa velocidad
     * Se implementa una funcion a fin de mover de forma manual los motores a paso, a la velocidad elegida.
     * Los tiempos antes mencionados se miden con proteus
     *
     * Queda pendiente arreglar el codigo fuente en detalles sobre el orden de las
     * sentencias a ejecutar para no perder pasos en la longitud del tornillo de medición.
     *
     * 3/jun/2013 Actualizacion
     * se modifica el fuente para que funcione el sistema con los nuevos drivers y las nuevas tarjetas
     * De igual forma se implementa el envio de datos por 3 bits para la LCD
     * Se actualiza la funcion RevisaPosicion para que ahora pueda leer los 4 bits del protocolo con la tarjeta de sensores
     * Se revisa el funcionamiento adecuado de las interrupciones externas
     * 
     * 4/jun/2013
     * Para utilizar el modo manual, las interrupciones han sido deshabilitadas, sin embargo, las banderas se disparan aun
     * sin entrar al código de interrupcion, por lo cual, si no se limpian las banderas, se entra automaticamente al codigo
     * de la interrupcion y el código se cicla, es por ello que se agregan las lineas
     * INTCONbits.INT0IF=0;
     * INTCON3bits.INT1IF=0;
     * 
     * 6/jun/2013
     * funcion autoposicionamiento está finalizada
     * S define una nueva velocidad de 40RPM para el movimiento del motor Eje X
     * Actualizacion de las definiciones en cabecera.h
     * 
     * @endverbatim
     */
    
    #include <pic18f2550.h>
    
    #define FOSC 48000000
    #include "simple_delay.h"
    #include "fLCD3bSDCC.h"
    #include "cabecera.h"
    
    __code char __at __CONFIG1L CONFIG1L = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L & _USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L;
    __code char __at __CONFIG1H CONFIG1H = _OSC_HS__HS_PLL__USB_HS_1H & _FCMEN_ON_1H & _IESO_ON_1H;
    __code char __at __CONFIG2L CONFIG2L = _PUT_ON_2L & _BODEN_ON_2L & _BODENV_4_2V_2L & _VREGEN_ON_2L;
    __code char __at __CONFIG2H CONFIG2H = _WDT_DISABLED_CONTROLLED_2H & _WDTPS_1_32768_2H;
    __code char __at __CONFIG3H CONFIG3H = _CCP2MUX_RC1_3H & _PBADEN_PORTB_4_0__CONFIGURED_AS_DIGITAL_I_O_ON_RESET_3H & _LPT1OSC_ON_3H & _MCLRE_MCLR_ON_RE3_OFF_3H;
    __code char __at __CONFIG4L CONFIG4L = _STVR_ON_4L & _LVP_OFF_4L & _ENHCPU_OFF_4L & _BACKBUG_OFF_4L;
    __code char __at __CONFIG5L CONFIG5L = _CP_0_OFF_5L & _CP_1_OFF_5L & _CP_2_OFF_5L & _CP_3_OFF_5L;
    __code char __at __CONFIG5H CONFIG5H = _CPB_OFF_5H;
    __code char __at __CONFIG6L CONFIG6L = _WRT_0_OFF_6L & _WRT_1_OFF_6L & _WRT_2_OFF_6L & _WRT_3_OFF_6L;
    __code char __at __CONFIG6H CONFIG6H = _WRTC_OFF_6H & _WRTB_OFF_6H;
    __code char __at __CONFIG7L CONFIG7L = _EBTR_0_OFF_7L & _EBTR_1_OFF_7L & _EBTR_2_OFF_7L & _EBTR_3_OFF_7L;
    __code char __at __CONFIG7H CONFIG7H = _EBTRB_OFF_7H;
    

    sorry comment in this close report but i can't with this problem.

    thanks in advance.
    Miguel

     
  • opps sorry this problem is fixed in SDCC 3.3 but the configuration bits can only defined by #pragma directive. :)

    Now my code is this (im sorry for my bad english structure)

    /** 
     * @File:   newmain.c
     * @Author: Miguel Montiel Martínez
     * @brief
     * Programa para el control de un dispositivo de automatización en mediciones
     * de susceptibilidad magnética en investigación paleo-ambiental a cargo del PhD Priyadarsi Debajyoti Roy
     * 
     * @verbatim
     * 16/05/2012  Actualizacion
     * son creadas las rutinas para elegir una entre tres velocidades sugeridas por el usuario
     * Se determina el numero de microsegundos que son necesarios para que los motores de paso tengan esa velocidad
     * Se implementa una funcion a fin de mover de forma manual los motores a paso, a la velocidad elegida.
     * Los tiempos antes mencionados se miden con proteus
     *
     * Queda pendiente arreglar el codigo fuente en detalles sobre el orden de las
     * sentencias a ejecutar para no perder pasos en la longitud del tornillo de medición.
     *
     * 3/jun/2013 Actualizacion
     * se modifica el fuente para que funcione el sistema con los nuevos drivers y las nuevas tarjetas
     * De igual forma se implementa el envio de datos por 3 bits para la LCD
     * Se actualiza la funcion RevisaPosicion para que ahora pueda leer los 4 bits del protocolo con la tarjeta de sensores
     * Se revisa el funcionamiento adecuado de las interrupciones externas
     * 
     * 4/jun/2013
     * Para utilizar el modo manual, las interrupciones han sido deshabilitadas, sin embargo, las banderas se disparan aun
     * sin entrar al código de interrupcion, por lo cual, si no se limpian las banderas, se entra automaticamente al codigo
     * de la interrupcion y el código se cicla, es por ello que se agregan las lineas
     * INTCONbits.INT0IF=0;
     * INTCON3bits.INT1IF=0;
     * 
     * 6/jun/2013
     * funcion autoposicionamiento está finalizada
     * S define una nueva velocidad de 40RPM para el movimiento del motor Eje X
     * Actualizacion de las definiciones en cabecera.h
     * 
     * @endverbatim
     */
    
    #include <pic18f2550.h>
    #define FOSC 48000000
    #include "simple_delay.h"
    #include "fLCD3bSDCC.h"
    #include "cabecera.h"
    
    /**
     * 20/jun/2013
     * Actualizacion a SDCC 3.3 donde se definen los bits de configuracion
     * mediante la directiva pragma, debido a que la version existente en
     * F18 no permite compilar PIC16 con pragma ni con __code char __at ...
     */
    #pragma config PLLDIV = 5, CPUDIV = OSC1_PLL2, USBDIV = 2
    #pragma config FOSC = HSPLL_HS, FCMEN = ON, IESO = ON
    #pragma config PWRT = ON, BOR = ON, BORV = 0, VREGEN = OFF
    #pragma config WDT = OFF, MCLRE = ON, LPT1OSC = ON
    #pragma config PBADEN = OFF, CCP2MX = ON
    #pragma config STVREN = ON, LVP = OFF
    #pragma config XINST = OFF, DEBUG = OFF
    
    /*
    __code char __at __CONFIG1L CONFIG1L = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L & _USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L;
    __code char __at __CONFIG1H CONFIG1H = _OSC_HS__HS_PLL__USB_HS_1H & _FCMEN_ON_1H & _IESO_ON_1H;
    __code char __at __CONFIG2L CONFIG2L = _PUT_ON_2L & _BODEN_ON_2L & _BODENV_4_2V_2L & _VREGEN_ON_2L;
    __code char __at __CONFIG2H CONFIG2H = _WDT_DISABLED_CONTROLLED_2H & _WDTPS_1_32768_2H;
    __code char __at __CONFIG3H CONFIG3H = _CCP2MUX_RC1_3H & _PBADEN_PORTB_4_0__CONFIGURED_AS_DIGITAL_I_O_ON_RESET_3H & _LPT1OSC_ON_3H & _MCLRE_MCLR_ON_RE3_OFF_3H;
    __code char __at __CONFIG4L CONFIG4L = _STVR_ON_4L & _LVP_OFF_4L & _ENHCPU_OFF_4L & _BACKBUG_OFF_4L;
    __code char __at __CONFIG5L CONFIG5L = _CP_0_OFF_5L & _CP_1_OFF_5L & _CP_2_OFF_5L & _CP_3_OFF_5L;
    __code char __at __CONFIG5H CONFIG5H = _CPB_OFF_5H;
    __code char __at __CONFIG6L CONFIG6L = _WRT_0_OFF_6L & _WRT_1_OFF_6L & _WRT_2_OFF_6L & _WRT_3_OFF_6L;
    __code char __at __CONFIG6H CONFIG6H = _WRTC_OFF_6H & _WRTB_OFF_6H;
    __code char __at __CONFIG7L CONFIG7L = _EBTR_0_OFF_7L & _EBTR_1_OFF_7L & _EBTR_2_OFF_7L & _EBTR_3_OFF_7L;
    __code char __at __CONFIG7H CONFIG7H = _EBTRB_OFF_7H;
    */
    
    //Zona de vectores de interrupcion
    static void isr_INTn() __interrupt 1
    {
       if(!medir)  //interrupcion por RB0
        {
          while(!medir);
          if(medir)
                {
                    flagMedir = false;
                    INTCONbits.INT0IF = 0;  //limpia la bandera de interrupcion RB0
                }
        }
        if(!enter)
          {
                while(!enter);
                if(enter)
                    {
                    flagEnter = false;
    
                    INTCON3bits.INT1IF = 0; //limpia la bandera de interrupcion RB1
                    }
                }
    
    }