Thursday, December 27, 2007

bootloader

Yes, building gcc is fun. Yes the painful self abuse of linux is fun. Trying to get some big debugger thing working that I will never use because I only care to load the flash, not fun.

I gave up trying to get the ftdi jtag working on Linux and quickly wrote a very simple bootloader. I currently use this on the Luminary Micro Stellaris LM3S6965 and LM3S1968 evaluation boards.

The bulk of what you need to know is in the bootload.txt file in the tarball.

bootload-20080106a.tar.gz
bootload.tar.gz

I used the serial port exposed by the on board ftdi chip. On ubuntu and perhaps elsewhere you might need to:

sudo rmmod ftdi_sio
sudo modprobe ftdi_sio vendor=0x0403 product=0xbcd9

(each time you plug in the board)

And that should provide you with /dev/ttyUSB0 and /dev/ttyUSB1 where /dev/ttyUSB1 is the port we are interested in. If you already have usb serial ports then the numbers will shift. On windows who knows how they are chosen you get COMsomething, unplug and replug and watch which port goes away and returns and there you go.

The bootloader has simple commands like

e 0x2000

To erase the page of flash starting at address 0x2000

And

w 0x2000 0x12345678

To write the value 0x12345678 to (an erased) address 0x2000

If you hold the up button on the 1968 or 6965 board (probably just the select button on the 811 if/when I get it going) during power up or a reset it goes into the bootloader waiting for commands. If you do not have that button pressed it jumps to address 0x2000. I have no support for interrupts at this time.

By the way its 115,200 8N1

There is an assembler and C LED blinker example (for now you have to go into the code and change probably one line to pick the board type before compiling/assembling) in the blinker directory. And on linux a simple loader program in the bload directory.

The linker script (memmap) for using my bootloader is

MEMORY
{
rom(RX) : ORIGIN = 0x00002000, LENGTH = 0x3E000
ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 64K
}
SECTIONS
{
.text : { *(.text*) } > rom
}

Which puts you at address 0x2000 in the flash, not 0x0000

If you want to use pretty much any of my examples without the bootloader use this linker script instead:


MEMORY
{
rom(RX) : ORIGIN = 0x00000000, LENGTH = 0x40000
ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 64K
}

SECTIONS
{
.text : { *(.text*) } > rom
}


Also since the bootloader handles the "vector table" which this chip and/or core uses (not the same as what you are used to from the ARM7) I simply branch to main when using the bootloader:


.cpu cortex-m3
.thumb
b main
.end

If you dont want to use the bootloader, use this instead:

.cpu cortex-m3
.thumb

.word 0x20010000 /* stack top address */
.word main /* reset routine location */
.word hang /* NMI ISR location */
.word hang /* Hard Fault ISR location */

hang: b .


20080106a adds support for the LM3S811 evaluation board.