ARM Toolchain

Updated (April 26, 2008)

Here’s my cheat-sheet for building a 64-bit GNU ARM toolchain (cross-compiler x64 to ARM). So far this has been working well for me on an LPC2148 (ARM7TDMI-S), i.e. gcc and gdb via OpenOCD JTAG.

Notes:

  1. Some builds (like binutils-2.18 and newlib-1.15) needed the setting MAKEINFO=/usr/bin/makeinfo to be passed to the make (binutils-2.17 and newlib-1.16 didn’t need this).
  2. Update: some systems (like Ubuntu 8.10) have strict checking turned on, where warnings are treated as errors. You may need to disable this the build of binutils and gdb using the –disable-werror configuration option.

Here are the steps:

environment (needed only for build):

export BINUTILS_VERSION=2.18
export GCC_VERSION=4.2.3
export NEWLIB_VERSION=1.16.0
export GDB_VERSION=6.8
.
export DIST=/opt1/gnuarm.dist    # tars will be downloaded here
export WORKDIR=/opt4/gnuarm.tmp    # tars will be unzipped and built here
export GNUARM_HOME=/opt/gnuarm   # Resulting binaries will be installed here
.
export SRC=$WORKDIR/src
export BUILD=$WORKDIR/build
export PREFIX=$GNUARM_HOME
export TARGET=arm-elf
.
md -p $DIST
md -p $SRC
md -p $BUILD
.
sudo mkdir -p $PREFIX

download:

cd $DIST
wget ftp://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.bz2
wget ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.bz2
wget ftp://ftp.gnu.org/gnu/gdb/gdb-${GDB_VERSION}.tar.bz2
wget ftp://sources.redhat.com/pub/newlib/newlib-${NEWLIB_VERSION}.tar.gz
wget http://www.gnuarm.com/t-arm-elf

untar:

cd $SRC
tar jxf $DIST/binutils-${BINUTILS_VERSION}.tar.bz2
tar jxf $DIST/gcc-${GCC_VERSION}.tar.bz2
tar jxf $DIST/gdb-${GDB_VERSION}.tar.bz2
tar zxf $DIST/newlib-${NEWLIB_VERSION}.tar.gz
cp $DIST/t-arm-elf gcc-${GCC_VERSION}/gcc/config/arm/t-arm-elf

binutils:

md $BUILD/binutils
cd $BUILD/binutils
$SRC/binutils-${BINUTILS_VERSION}/configure –target=$TARGET –prefix=$PREFIX –enable-interwork –enable-multilib
make all install 2>&1 | tee make.out

gcc core:

md $BUILD/gcc
cd $BUILD/gcc
$SRC/gcc-${GCC_VERSION}/configure –target=$TARGET –prefix=$PREFIX
–enable-interwork –enable-multilib –enable-languages=”c,c++” –with-newlib –with-headers=$SRC/newlib-${NEWLIB_VERSION}/newlib/libc/include

make all-gcc install-gcc 2>&1 | tee make.out

newlib:

md $BUILD/newlib
cd $BUILD/newlib
$SRC/newlib-${NEWLIB_VERSION}/configure –target=arm-elf –prefix=$PREFIX –enable-interwork –enable-multilib

make all install 2>&1 | tee make.out

gcc (phase two):

cd $BUILD/gcc
make all install 2>&1 | tee make.out

gdb:

md $BUILD/gdb
cd $BUILD/gdb
$SRC/gdb-${GDB_VERSION}/configure –target=$TARGET –prefix=$PREFIX –enable-interwork –enable-multilib

make all install 2>&1 | tee make.out

post-setup:

echo ‘export GNUARM_HOME=/opt/gnuarm’ >> ~/.profile
echo ‘export PATH=$GNUARM_HOME/bin:$PATH’ >> ~/.profile

The scripts can be downloaded from here.

ARM boards

Just got back from a trip to Chicago – Oak Park, a renovated “gentrified” neighbourhood, west of Chicago. Just spent the night researching a good ARM board to buy. Narrowed it down to these (all these boards have USB and SD card reader):

ARM7TDMI-S boards:

  • Olimex SAM7-P256 (SAM7-Pxxx Rev. E) – Atmel AT91SAM7S256, 256K Flash, 64K RAM, 60MHz, 18MHz crystal. $87.
  • Olimex LPC-P2148 – NXP LPC2148, 512K Flash, 32K+8K RAM, 60MHz, 12MHz crystal. $77.

.
ARM7TDMI-S boards w/Ethernet:

  • Olimex SAM7-LA2 – Atmel AT91SAM7A2, 1MB Flash, 4MB SRAM, 30MHz, 6MHz crystal. $140.
  • Olimex SAM7-EX256 – Atmel AT91SAM7X256, 256K Flash, 64K RAM, 55MHz, 18MHz crystal. This board is loaded with stuff. $120.

.
ARM920T boards w/MMU (for running embedded Linux):

  • Olimex CS-E9302 – Cirrus Logic EP9302, 16MB Flash, 32MB SDRAM, 200MHz. Cirrus Logic has a very good linux forum. $180.
  • Olimex SAM9-L9260 – Atmel AT91SAM9260, 512MB NAND Flash, 64MB SDRAM, 180MHz, 18MHz crystal. $217.
  • … or just get another Slug – XScale IXP420 (ARMv5TE), 8MB Flash, 32MB SDRAM, 266MHz. $80.

Arduino GPS

Just to get my hands dirty and wrap it up with the AVR’s, I created a GPS data logger – using an Arduino board, GPS receiver chip, 4×20 LCD, and a uALFAT microSD board.

A good document on NMEA commands and data formats used by GPS chips is here. Regarding the GPS unit, it was SiRF vs Trimble, and I went for SiRF, the SiRF III (the EM-406A by USGlobalSat). I picked it over the Trimble Lassen IQ and the Parallax.

Great learning exercise for getting down to the bare-metal. I decided to write it in raw C (UART driver, LCD driver, flash data logger,…), all from scratch, instead of Arduino’s Wiring language. This amounts to pretty much reading most of the 300 page data sheet for the MCU, giving you a thorough understanding of all aspects of the MCU – GPIO, clocks, counters, interrupts, UART, SPI, I2C,… all related considerations like registers, masks, timings, memory organization,…

Arduino LCD

My first step, in my foray into embedded systems: interfaced a 4×20 character LCD panel to the Arduino. Details on interfacing any Hitachi HD44780 based LCD panel can be found here.

Went for the default parallel LCD’s. They’re cheap, about $15 for a 20×4 panel on eBay (HD44780). The serial ones cost about 2-3 more. These LCD panels allow you to use 4 data lines (with some bit-banging) instead of 8. Get one that is STN and transflective (vs reflective and transmissive), known for better contrast and brighter.

Check out also LCDProc.

The Arduino

Just got it today :-). The Arduino is a great learning platform for anyone interested in the embedded world. The entire platform is open (hardware schematics, bootloader, lots of examples, etc.).

Comes with a programming language that abstracts out lot of the bit-level stuff… but for learning purposes I’d recommend just using straight C – i.e. to get right down to the bare metal. You’ll probably end up reading two-thirds of the 350 page ATmega168 specs. Atmel’s AVR docs are really well done, with assembly language and bit-level C-language code snippets. Ubuntu has a ready-made GNU C toolchain for the AVR which works quiet well. There is also an Eclipse plugin.

Also, check this site out: Atmel AVR Application Notes. Tons of stuff. You don’t really need to buy any embedded systems books. Also Atmel AVR 8-bit Instruction Set.

ATmega128

The Atmel ATmega128 AVR is a nice little full featured general purpose 8-bit MCU (i.e. not including MCUs which add on a host of other features like controllers for LCD, USB, Ethernet MAC, DSP, MMU, etc.).

For my own quick reference:

Feature ATmega128 ATmega168 ATmega8
Flash 128K 16K 8K
SRAM 4K 1K
512
EEPROM 4K 1K
512
UART 2 1
1
8-bit Timer 2 2
2
16-bit Timer 2 1
1
PWM (channels) 6+2 5
3
10-bit A/D (channels)
8 6
8
DebugWire/OCD Y

Analog Y

JTAG Y

SPI 1 1
1
TWI 1 1
1

Which RTOS?

After scouring through a number of MCU’s I’ve decided to go with the Atmel AVR, in particular the ATmega168.

But then, my recent adventure into the Slug’s hardware, got me thinking ARM. I settled for Atmel’s AT91SAM7 series of ARM MCU’s.

My next thought was how I can run Debian/ARM on it. But unfortunately that was quickly ruled out – as the largest of the 7S or 7X series has only 512K Flash and 128K SRAM. Note that the 7SE series has an external memory bus.

So what can I squeeze into 256K Flash and 64K RAM? My hunt came up with these (in terms of the number of microcontrollers each has been ported to):

  1. FreeRTOS (free)
  2. uC/OS-II (commercial)
  3. eCos (pdf book: Embedded Software Development with eCos)
  4. TNKernel (free)

And these bootloaders:

  1. u-Boot
  2. Redboot
  3. Apex