Microchip MPLAB C30 compiling on a Linux system

This page tries to explain how to compile the Microchip MPLAB C30 cross-compiling tool chain for pic24 & dsPIC on a Linux based system.
Those information mainly come from other documentations (like  1,  2,  3 or  4) and have been tested for the v3.12 of MPLAB ASM 30 & C Compiler for dsPIC & PIC24 DSCs.

This procedure will explain first how to compile the PIC30 binutils, then how to compile the PIC30 GCC and finally how to import the nonfree library files into our new PIC30 cross compilation tool chain.
Actually the Mplab PIC30 compiler and linker sources come in two different packages released under the GPL by Microchip. The specific 16-bit linker scripts, headers and libraries are upon the Microchip property, so you will have to retrieve them from a standard C30 installation. Note that I tried to adapt this procedure for the newer version (v3.20), but I didn't succeed to get the compilation working. Hope someone else will achieve this next step!

Prerequisites

Before starting, you will need to have GCC, Bison, Flex, and Tofrodos/Dos?2unix utility available on your system.

sudo apt-get install build-essential bison flex tofrodos

You may need some other packages to successfully build the tool chain.

PIC30 Binutils

Get the binutils 3.12 source package from the  MPLAB IDE archives download page and extract it.

mkdir c30binutils
cd c30binutils
wget http://ww1.microchip.com/downloads/en/DeviceDoc/mplabalc30v3_12.tar.gz
tar -xvvf mplabalc30v3_12.tar.gz

Convert the Windows end-of-lines into POSIX ones for the acme folder sources

cd acme
find . -type f -exec dos2unix '{}' ';'

Download and extract John Steele Scott’s patches available  here:

cd ..
tar -jxvf pic30-binutils-3.11b.tar.bz2

Those patches are necessary to avoid running tests during the build as the testsuite is not provided by Microchip in its source packages. As you can see, they have been issued for the 3.11b C30 version. That's why we won't be able to apply all of them directly on the sources. This is the case for pic30-binutils-3.11b/patches/search-path-fix.diff. I did not took time to update it, but manually applying it on source code is not too much pain (vim is your friend to do that)!

For the other ones, execute:

patch -p0 < pic30-binutils-3.11b/patches/binutils-makefile_in.diff
patch -p0 < pic30-binutils-3.11b/patches/allow-empty-device-info-file.diff

We touch the files from the acme directory, so the yacc and flex files will effectively be parsed during the build.

cd acme/
find . -name *.y -type f -exec touch '{}' ';'
find . -name *.l -type f -exec touch '{}' ';'

Now configure the package to build the pic30-coff binutils, then make and install it.

CFLAGS=-DMCHP_VERSION="v3.12-Ubuntu" ./configure --prefix=/usr/local/pic --target=pic30-coff
make
sudo make install

If needed, you can also build the pic30-elf binutils by changing the target configuration option.

sudo make distclean
find . -name *.y -type f -exec touch '{}' ';'
find . -name *.l -type f -exec touch '{}' ';'
CFLAGS=-DMCHP_VERSION="v3.20-Ubuntu" ./configure --prefix=/usr/local/pic --target=pic30-elf
make
sudo make install

PIC30-GCC

Get the Mplab 3.12 GCC source archive file from the  MPLAB IDE archives download page and extract it.

mkdir c30gcc
cd c30gcc
wget http://ww1.microchip.com/downloads/en/DeviceDoc/mplabc30v3_12.tar.gz
tar -zxvf mplabc30v3_20.tar.gz

Convert to UNIX files

find . -type f -exec dos2unix '{}' ';'

Download John Steele Scott’s patches available  here.
Then extract and apply them:

tar -jxvf pic30-gcc-3.11b.tar.bz2
patch -p0 < pic30-gcc-3.11b/patches/pic30-standard-prefix.diff
patch -p0 < pic30-gcc-3.11b/patches/search-path-fix.diff
patch -p0 < pic30-gcc-3.11b/patches/libiberty-testsuite.diff
patch -p0 < pic30-gcc-3.11b/patches/make-relative-prefix.diff
patch -p0 < pic30-gcc-3.11b/patches/resource-path.diff
patch -p0 < pic30-gcc-3.11b/patches/t-pic30.diff

Touch the source file

find . -name *.y -type f -exec touch '{}' ';'
find . -name *.l -type f -exec touch '{}' ';'

Then configure the package to build a pic30-coff gcc, then make and install it.

mkdir gcc-build
cd gcc-build
CFLAGS=-DMCHP_VERSION="v3.12-Ubuntu" ../gcc-4.0.2/gcc-4.0.2/configure --prefix=/usr/local/pic --target=pic30-coff --enable-languages=c
make
sudo make install

Add some symbolic links between gcc and the binutils

sudo ln -s /usr/local/pic/bin/pic30-coff-as /usr/local/pic/libexec/gcc/pic30-coff/4.0.3/
sudo ln -s /usr/local/pic/bin/pic30-coff-ld /usr/local/pic/libexec/gcc/pic30-coff/4.0.3/

Repeat those two last steps to obtain the pic30-elf gcc

sudo rm -rf ../gcc-build/*
find .. -name *.y -type f -exec touch '{}' ';'
find .. -name *.l -type f -exec touch '{}' ';'
CFLAGS=-DMCHP_VERSION="v3.12-Ubuntu" ../gcc-4.0.2/gcc-4.0.2/configure --prefix=/usr/local/pic --target=pic30-elf --enable-languages=c
make
sudo make install
sudo ln -s /usr/local/pic/bin/pic30-elf-as /usr/local/pic/libexec/gcc/pic30-elf/4.0.3/
sudo ln -s /usr/local/pic/bin/pic30-elf-ld /usr/local/pic/libexec/gcc/pic30-elf/4.0.3/

If everything went right, we should now have a working cross-compiling tool chain for dsPIC & PIC24 DSCs.
Let's give it a simple try:

echo "int main(void) { return 0; }" > test.c
/usr/local/pic/bin/pic30-coff-gcc-4.0.3 -c test.c

You cannot link the program without the linker files (*.gld files from Microchip’s libc). But you can check the compilation result by:

/usr/local/pic/bin/pic30-coff-objdump -S test.o

Import the non-free Microchip resources

To complete the toolchain installation, we need to retrieve dsPIC & PIC24 headers, libraries and link scripts from Microchip C30 v3.12 release.

First we will have to copy the following folders into the /usr/local/pic/pic30-nonfree directory from the C30 installation:

  • include
  • lib
  • support

Then copy the info/c30_device.info file from the C30 installation into the /usr/local/pic/info folder and create some symbolic links.

sudo ln -s /usr/local/pic/info/c30_device.info /usr/local/pic/c30_device.info
sudo ln -s /usr/local/pic/info/c30_device.info /usr/local/pic/libexec/gcc/pic30-coff/c30_device.info

A few hints

CPU not recognized

If you get the following error during the linking step:

$ /usr/local/pic/bin/pic30-coff-gcc-4.0.3 -mcpu=30F4013  -o test test.c
pic30-coff-cc1: warning : Provide a resource file
pic30-coff-cc1: error: Invalid -mcpu option.  CPU 30F4013 not recognized.

Add the following option to solve it: -mresource=/usr/local/pic/info/c30_device.info

Syntax error on GLD file

During the linking step using pic30-coff-ld or pic30-elf-ld, if you get a syntax error on a Microchip GLD file at a line containing the OPTIONAL keyword, that's probably because you did not touch the binutils yacc and flex files correctly before building the binutils.

You have to touch those files (with .y and .l extension) and not the whole folder[[BR]] Then rebuild and install the binutils.

Unresolved symbol _reset

During the linking step using pic30-coff-ld or pic30-elf-ld, if you get an "unresolved symbol _reset" error, you have to add a linking option to specify the usage of the pic30 library: -lpic30.

Buffer overflow with pic30-coff-ar

On recent gcc version (at least from version 4.4.1), they introduced a lightweight support for checking buffer overflows at runtime. The fact is such a buffer overflow (non-critical) is detected in the c30 archiver at runtime. To fix this issue I applied the patch available  here.