I got the at91eb40a to run with free software. Here's how I did it. First, I decided to start with a simple assembly language program. Here is the program adapted from "Embedded System Design On a Shoestirng" book. My environment was win2k and cygwin. I built the cross development tools from the latest sources with the following script:
#!/usr/bin/bash
#binutils-2.14.tar.gz #gcc-3.3.1.tar.gz #gdb-6.0.tar.gz #newlib-1.9.0.tar.gz
echo "building gnu toolchain for ARM" tar xzvf binutils-2.14.tar.gz tar xzvf gcc-3.3.1.tar.gz tar xzvf newlib-1.9.0.tar.gz tar xzvf gdb-6.0.tar.gz
echo "building binutils" cd build-binutils ../binutils-2.14/configure --target=$TARGET --prefix=$PREFIX make all install 2>&1 | tee make.log cd ..
echo "building bootstrap cross compiler" cd build-gcc ../gcc-3.3.1/configure --target=$TARGET --prefix=$PREFIX \ --with-newlib --without-headers --with-gnu-as \ --with-gnu-ld --disable-shared --enable-languages=c make all-gcc install-gcc 2>&1 | tee make.log cd ..
echo "building newlib" cd build-newlib ../newlib-1.9.0/configure --target=$TARGET --prefix=$PREFIX make all install 2>&1 | tee make.log cd ..
echo "building cross compiler" cd build-gcc && rm -rf * ../gcc-3.3.1/configure --target=$TARGET --prefix=$PREFIX \ --with-gnu-as --with-gnu-ld --enable-languages=c,c++ make all install 2>&1 | tee make.log cd ..
echo "building debugger" cd build-gdb ../gdb-6.0/configure --target=$TARGET --prefix=$PREFIX make all install 2>&1 | tee make.log cd ..
- here is test.s: ==================
@----------------------------------------------------------------------- @ Embedded Systems Development on a Shoestring @ @ Example project 1 - EB40 LED Flasher @ @ Lewin A.R.W. Edwards ( snipped-for-privacy@zws.com), Jun-2002.
.section .text .code 32 .globl vectors
@ total = 32 + 60 + 72 = 164 bytes, the same size as test.bin produced by @ the make file.
@----------------------------------------------------------------------- @ In a ROM-startup program, this would be the interrupt vector area. As this @ program is intended for RAM startup, we simply have our init code at the @ "reset handler" (entry point). @-----------------------------------------------------------------------
@ 32 bytes:
vectors: b reset @ Reset b . @ Undefined instruction b . @ SWI b . @ Prefetch abort b . @ Data abort b . @ reserved vector b . @ irqs b . @ fast irqs
@-----------------------------------------------------------------------
@ 60 bytes
reset: ldr r4,PIO_SODR ldr r5,PIO_CODR
ldr r6,=0x00010000 @ Bit 16 d1 LED on the EB40A
main: str r6,[r4] @ Turn on LED
ldr r0,delay_constant ldr r1,=0
loop1: sub r0,r0,#1 cmp r0,r1 bne loop1
str r6,[r5] @ Turn off LED
ldr r0,delay_constant
loop2: sub r0,r0,#1 cmp r0,r1 bne loop2
b main
@ 18*4 = 72 bytes
@----------------------------------------------------------------------- @ CONSTANTS @-----------------------------------------------------------------------
@-------------------------- @ pio registers: @--------------------------
PIO_PER: .word 0xffff0000 @ PIO Enable Register Write Only PIO_PDR: .word 0xffff0004 @ PIO Disable Register Write Only PIO_PSR: .word 0xffff0008 @ PIO Status Register Read Only 0x01FFFFFF (see also Table 10) PIO_OER: .word 0xffff0010 @ Output Enable Register Write Only PIO_ODR: .word 0xffff0014 @ Output Disable Register Write Only PIO_OSR: .word 0xffff0018 @ Output Status Register Read Only 0 PIO_IFER: .word 0xffff0020 @ Input Filter Enable Register Write Only PIO_IFDR: .word 0xffff0024 @ Input Filter Disable Register Write Only PIO_IFSR: .word 0xffff0028 @ Input Filter Status Register Read Only 0 PIO_SODR: .word 0xffff0030 @ Set Output Data Register Write Only PIO_CODR: .word 0xffff0034 @ Clear Output Data Register Write Only PIO_ODSR: .word 0xffff0038 @ Output Data Status Register Read Only 0 PIO_PDSR: .word 0xffff003C @ Pin Data Status Register Read Only (see Note 1) PIO_IER: .word 0xffff0040 @ Interrupt Enable Register Write Only ? PIO_IDR: .word 0xffff0044 @ Interrupt Disable Register Write Only ? PIO_IMR: .word 0xffff0048 @ Interrupt Mask Register Read Only 0 PIO_ISR: .word 0xffff004C @ Interrupt Status Register Read Only (see Note 2)
@-------------------------- @ variables: @--------------------------
delay_constant: .word 0x00200000 @ Provides a decent delay period
- here is the makefile: ========================= ASFLAGS = -mcpu=arm7tdmi -gstabs LDFLAGS = -Teb40A-ram.ld -nostartfiles -Lgcc
-L. OBJS = test.o EXE = test.elf BIN = test.bin OBJCOPYFLAGS = -O binary
$(BIN): $(EXE) arm-elf-objcopy $(OBJCOPYFLAGS) $(EXE) $(BIN)
$(EXE): $(OBJS) arm-elf-gcc $(LDFLAGS) -o $(EXE) $(OBJS)
%.o:%.s arm-elf-as $(ASFLAGS) $< -o $@
clean: rm -f $(OBJS) rm -f $(EXE) rm -f $(BIN)
- here is the ld file: =======================
/* Linker script for Atmel EB40A */
/* For standardization, the entry-point is called "vectors", although for these programs, this is not actually the interrupt vector table.
*/ENTRY(vectors)
SEARCH_DIR(.)
/* There is a single memory segment, representing the 256K on-board SRAM. */
MEMORY { sram : org = 0x00300000, len = 0x00040000 /* 256KBytes of SRAM */ }
SECTIONS { .text : { *(.text); . = ALIGN(4); *(.glue_7t); . = ALIGN(4); *(.glue_7); . = ALIGN(4); etext = .; } > sram
.data ADDR(.text) + SIZEOF(.text) : { datastart = .; __data_start__ = . ; *(.data) . = ALIGN(4); __data_end__ = . ; edata = .; _edata = .; }
.bss ADDR(.data) + SIZEOF(.data) : { __bss_start__ = . ; *(.bss); *(COMMON) __bss_end__ = . ; }
end = .; _end = .; __end__ = .;
/* Symbols */ .stab 0 (NOLOAD) : { [ .stab ] }
.stabstr 0 (NOLOAD) : { [ .stabstr ] } }
- =========================
After running make I obtained test.bin. I never could get gdb to work, so I decided to try bincom.exe. Here's how:
- hold down sw2 and press reset. Do not let go of sw2 until all of the d1-d8 are lit. Then let go and d2 will remain lit.
- run bincom.exe. Configure for 115200 baud, 8 data bits, no parity,
- "send file" and select "test.bin". exit bincom.
- press and release s2 and you should see d1 flashing about 3 times per second.
I'm posting these instructions in case someone else has trouble getting the at91eb40a running with free software like I did. Next I'll try a C program.
I still need to get arm-elf-gdb working in cygwin with the Angel debug monitor. I think that the gdb program is broken, so I may look into finding the bug.
-- William