chipKIT® Development Platform

Inspired by Arduino™

An issue with compiling by chipkit32 pic32-gcc vs xc32

Created Tue, 21 Aug 2012 23:10:33 +0000 by begoon


Tue, 21 Aug 2012 23:10:33 +0000


Can anybody point out the correct direction where to dig because I'm totally stuck.

I have a tiny program for 32MX795F512H which turns on a led. Simple.

#include <p32xxxx.h>
#include <plib.h>

void main() {
    TRISEbits.TRISE1 = 0;
    PORTEbits.RE1 = 1;
    while (1);

If I compile it by XC32:

xc32-gcc -o image.out main.c -mprocessor=32MX795F512H -Wl,--script=./LinkScript.ld.x32

it perfectly compiles and works after uploading to the chip. The led turns on. The link script LinkScript.ld.x32 is attached.

But when I build by via the chipkit32 compiler (version pic32-gcc (chipKIT) 4.5.1 chipKIT Compiler for PIC32 MCUs v1.30-20110506):

pic32-gcc -o image.out main.c -mprocessor=32MX795F512H -T ./LinkScript.ld.chipkit32

the program doesn't start.

The linker scripts are identical except one simple change:

--- LinkScript.ld.chipkit32.txt	2012-08-21 23:56:28.000000000 +0100
+++ LinkScript.ld.xc32.txt	2012-08-21 23:56:18.000000000 +0100
@@ -29,10 +29,9 @@
  * Processor-specific peripheral libraries are optional
  * For interrupt vector handling

The XC32 compile requires it but pic32-gcc doesn't understand it.

I need the linker script to preserve the boot loader in my board.

I compared the assembly output (by -S) from the both compilers, and it is the same. So I suspect that something wrong with linking. Obviously, pic32-gcc links up the invalid binary.

Can somebody advise what can be an issue here?




Wed, 22 Aug 2012 00:15:54 +0000

I think there should be more differences between your chipKIT linker script and the XC32 linker script. For instance, the chipKIT linker script should set up the stack/heap as well as initialized data. Please see these examples:

Basically, the chipKIT linker scripts are more similar to the C32 v1.xx linker scripts than the XC32 linker scripts.


Wed, 22 Aug 2012 09:53:45 +0000

The link script I'm using for chipkit32 linking works without any changes at all with C32 2., but I see that you mentioned C32 1..

I've compared the scripts you pointed with against my ones, and I haven't found any meaningful differences in term of the stack. But I've found a big chunk in your scripts which is missing it my ones. Seems it is related to 'crt' initilization/allocation.

Also I see the target binary generated by the chipkit32 compiler is visibly smaller than the file from XC32. Maybe it doesn't link/add crt.o or something.

.init      :
	KEEP (*crti.o(.init))
	KEEP (*crtbegin.o(.init))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o *crtn.o ).init))
	KEEP (*crtend.o(.init))
    KEEP (*crtn.o(.init))
    . = ALIGN(4) ;
  }  >kseg0_program_mem

  .fini       :
    KEEP (*(.fini))
    . = ALIGN(4) ;
  } >kseg0_program_mem

  .preinit_array     :
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    . = ALIGN(4) ;
    PROVIDE_HIDDEN (__preinit_array_end = .);

  .init_array     :
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array))
    . = ALIGN(4) ;
    PROVIDE_HIDDEN (__init_array_end = .);

  .fini_array     :
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array))
    . = ALIGN(4) ;
    PROVIDE_HIDDEN (__fini_array_end = .);

  .ctors        :
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    . = ALIGN(4) ;

  .dtors          :
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    . = ALIGN(4) ;

  .preinit_array    :
    KEEP (*(.preinit_array))
    . = ALIGN(4) ;

  /* Read-only sections */
  .header_info ALIGN(4) :
    _image_header_info = . ;
    LONG(SIZEOF(.header_info))          /* size of this structure       */
    LONG(0xFFFFFFFF)                    /* bootloader version           */
    KEEP(*(.mpide_version))             /* MPIDE build version          */
    LONG(0xFFFFFFFF)                    /* booloader capabilities       */
    LONG(0xFFFFFFFF)                    /* VID and PID                  */
    LONG(_IMAGE_TYPE)                   /* image type and options       */
    LONG(_JUMP_ADDR)                    /* image execution address      */
    LONG(_ebase_address)                /* image base address           */
    LONG(_IMAGE_FLASH_SIZE)             /* size of image flash used     */
    LONG(ORIGIN(kseg0_eeprom_mem))      /* eeprom location              */
    LONG(LENGTH(kseg0_eeprom_mem))      /* eeprom size                  */   
    LONG(ORIGIN(configsfrs))            /* config bits location         */
    LONG(LENGTH(configsfrs))            /* config bits size             */
    LONG(_ram_header_addr)              /* ram header pointer           */
    LONG(SIZEOF(.ram_exchange_data))    /* ram Header size              */
    LONG(0xFFFFFFFF)                    /* what the bootloader skips    */
    _image_header_info_end = . ;
  } > kseg0_program_mem
  ASSERT (SIZEOF(.header_info) == 64, "MPIDE Version not specfied correctly")