got eb40a running with free software: here's how

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 ..

  1. 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

  1. 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)

  1. 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 ] } }

  1. =========================

After running make I obtained test.bin. I never could get gdb to work, so I decided to try bincom.exe. Here's how:

  1. 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.

  1. run bincom.exe. Configure for 115200 baud, 8 data bits, no parity,

1 stop bit, no flow control

  1. "send file" and select "test.bin". exit bincom.

  2. 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

Reply to
William Wuister
Loading thread data ...

I modified the main.c and boot.s from Lewin's book and am trying to get the code to run on the eb40a board. I got the assembly language version working.

If anyone has an idea why the following doesn't work please post it to the group.

boot.s: ================

.section .text .code 32 .globl vectors

@---------------------------------------------------------------------------- @ 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). @----------------------------------------------------------------------------

vectors: b reset @ Reset b . @ Undefined instruction b . @ SWI b . @ Prefetch abort b . @ Data abort b . @ reserved vector b . @ irqs b . @ fast irqs

@---------------------------------------------------------------------------- @ Entry-point code

reset:

@ Begin by clearing out the .bss section

ldr r1, bss_start ldr r2, bss_end ldr r3, =0

clear_bss: cmp r1,r2 strne r3,[r1],#+4 bne clear_bss

ldr r13,stack_pointer @ Initialize the stack pointer

bl main

b vectors

@----------------------------------------------------------------------------

@ Miscellaneous constants

stack_pointer: .word _stack_top bss_start: .word __bss_start__ bss_end: .word __bss_end__

.end

main.c: ==============

#define PIO_SODR 0xffff0030 #define PIO_CODR 0xffff0034

#define RED_LED 0x00010000 #define TIMEOUT 0x00200000

/* Quick and dirty macros to write a register or memory location word, halfword or byte */

#define WRITEREGW(addr,value) *((volatile unsigned int *) (addr)) = (value) #define WRITEREGH(addr,value) *((volatile unsigned short *) (addr)) = (value) #define WRITEREGB(addr,value) *((volatile unsigned char *) (addr)) = (value)

int main(void) { register int i;

while (1) { for (i=TIMEOUT; i>0; i--) { }

WRITEREGW(PIO_SODR, RED_LED); // turn on led

for (i=TIMEOUT; i>0; i--) { }

WRITEREGW(PIO_CODR, RED_LED); // turn off led }

}

makefile: =============

# Embedded Systems on a Shoestring # Example project #2 - EB40 LED Flasher in C # # Lewin A.R.W. Edwards ( snipped-for-privacy@zws.com), Jun-2002.

# Omit debug directives, include high-level and assembly source.

CFLAGS = -g -I. -mcpu=arm7tdmi ASFLAGS = -mcpu=arm7tdmi -gstabs LDFLAGS = -Teb40a-ram.ld -nostartfiles -Lgcc -L. OBJS = boot.o main.o EXE = test.elf OBJCOPYFLAGS = -O binary BIN = test.bin

$(BIN): $(EXE) arm-elf-objcopy $(OBJCOPYFLAGS) $(EXE) $(BIN)

$(EXE): $(OBJS) arm-elf-gcc $(LDFLAGS) -o $(EXE) $(OBJS)

%.o:%.c arm-elf-gcc -c $(CFLAGS) $< -o $@

%.o:%.s arm-elf-as $(ASFLAGS) $< -o $@

clean: rm -f $(OBJS) rm -f $(EXE) rm -f $(BIN)

.ld file: =============

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__ = . ; _stack_bottom = . ; . += 0x800 ; _stack_top = . ; }

end = .; _end = .; __end__ = .;

/* Symbols */ .stab 0 (NOLOAD) : { [ .stab ] }

.stabstr 0 (NOLOAD) : { [ .stabstr ] } }

When I run make, I get a test.bin that is 216 bytes long. The test.bin that I get from the assembly language version is 164 bytes long.

I load this new test.bin the same way that I loaded the other one, but there is no blinking.

Any ideas?

thanks, William

Reply to
William Wuister

[snip...snip...]

Thanks for the posting. I have the board as well, and Lewin's book of course, but what with one thing and another (including hurricanes) I didn't get much beyond building the toolchain before other priorities got in the way, it migrated towards the back of the workbench, the cats hid it under the sofa, or maybe it was LGM... Anyway, I need to get kickstarted again.

--
Rich Webb   Norfolk, VA
Reply to
Rich Webb

--- clip clip ---

@---------------------------------------------------------------------------

-

@---------------------------------------------------------------------------

-

In a RAM-start program, you can skip the vector part totally.

In a ROM-start program, you need to set up the chip-select unit and cancel remap before doing the C run environment setup.

If your application does not trust the aeons-old bad C programmer habit of having the uninitialised variables zeroed, you do not even need to clear .bss.

In ROM-based code, you need to copy the initialised data (.data) image to its place in RAM.

-----

The 'register' attribute is ignored - a RISC compiler nearly always tries to use the registers for often-used variables.

If it's not sure beforehand, you should enable the peripheral use of the LED pin and its output enable before entering the blink loop. This applies to both test code pieces.

Does the LED light with half intensity?

It's fairly possible that the delay loops are optimised away - check the generated assembly code. GCC gives the listing with:

gcc -c -Wa,-ahlms=myfile.lst myfile.c

If that's the case, change the loop:

for ( i = TIMEOUT; i > 0; i--) { asm volatile(";"); }

You can also disassemble the .elf file:

arm-elf-objdump -D myfile.elf >myfile.dis

and check what is really in the binary image.

If you're not going to debug the target, drop the -g flag and add -O2.

It's usually considered Not a Good Idea to name a piece of code 'test' - it's a built-in command in UNIX-like shells.

HTH

Tauno Voipio tauno voipio @ iki fi

Reply to
Tauno Voipio
  1. Here is the disassembly of test.bin from the c program ================================================

test.elf: file format elf32-littlearm

Disassembly of section .text:

00300000 : 300000: ea000006 b 300020 300004: eafffffe b 300004 300008: eafffffe b 300008 30000c: eafffffe b 30000c 300010: eafffffe b 300010 300014: eafffffe b 300014 300018: eafffffe b 300018 30001c: eafffffe b 30001c

00300020 : 300020: e59f1020 ldr r1, [pc, #32] ; 300048

300024: e59f2020 ldr r2, [pc, #32] ; 30004c 300028: e3a03000 mov r3, #0 ; 0x0

0030002c : 30002c: e1510002 cmp r1, r2 300030: 14813004 strne r3, [r1], #4 300034: 1afffffc bne 30002c 300038: e59fd004 ldr sp, [pc, #4] ; 300044

30003c: eb000003 bl 300050 300040: eaffffee b 300000

00300044 : 300044: 003008d8 ldreqsb r0, [r0], -r8

00300048 : 300048: 003000d8 ldreqsb r0, [r0], -r8

0030004c : 30004c: 003000d8 ldreqsb r0, [r0], -r8

00300050 : 300050: e1a0c00d mov ip, sp 300054: e92dd800 stmdb sp!, {fp, ip, lr, pc} 300058: e24cb004 sub fp, ip, #4 ; 0x4 30005c: e24dd004 sub sp, sp, #4 ; 0x4 300060: e1a00000 nop (mov r0,r0) 300064: e3a03602 mov r3, #2097152 ; 0x200000 300068: e50b3010 str r3, [fp, -#16] 30006c: e51b3010 ldr r3, [fp, -#16] 300070: e3530000 cmp r3, #0 ; 0x0 300074: ca000000 bgt 30007c 300078: ea000003 b 30008c 30007c: e51b3010 ldr r3, [fp, -#16] 300080: e2433001 sub r3, r3, #1 ; 0x1 300084: e50b3010 str r3, [fp, -#16] 300088: eafffff7 b 30006c 30008c: e3e03cff mvn r3, #65280 ; 0xff00 300090: e24330cf sub r3, r3, #207 ; 0xcf 300094: e3a02801 mov r2, #65536 ; 0x10000 300098: e5832000 str r2, [r3] 30009c: e3a03602 mov r3, #2097152 ; 0x200000 3000a0: e50b3010 str r3, [fp, -#16] 3000a4: e51b3010 ldr r3, [fp, -#16] 3000a8: e3530000 cmp r3, #0 ; 0x0 3000ac: ca000000 bgt 3000b4 3000b0: ea000003 b 3000c4 3000b4: e51b3010 ldr r3, [fp, -#16] 3000b8: e2433001 sub r3, r3, #1 ; 0x1 3000bc: e50b3010 str r3, [fp, -#16] 3000c0: eafffff7 b 3000a4 3000c4: e3e03cff mvn r3, #65280 ; 0xff00 3000c8: e24330cb sub r3, r3, #203 ; 0xcb 3000cc: e3a02801 mov r2, #65536 ; 0x10000 3000d0: e5832000 str r2, [r3] 3000d4: eaffffe2 b 300064 Disassembly of section .data:

  1. The led does not blink at half intensity ==================================

  2. ==

The assembly version works, so I assume that the hardware does not need to be configured for the C version. Remember that I have to use bincom, since gdb hangs when it tries to connect to angel.

William

Reply to
William Wuister

Aha - you're running it in the internal RAM without remap.

Here (r1) == (r2), the code is just run through.

Function prolog:

Main loop:

Delay loop: 2 million turns of 12 clocks each

Write bit 16 to 0xffff0030

Loop setup:

Delay loop:

Write bit 16 to 0xffff0034

Loop back

That's OK - the delay loops are not gone.

Please post the corresponding disassembly of the assembler language version.

I do not know the EB40 too well - my eval board is much older, and the newer systems I'm running are built from scratch.

Are you sure that the processor runs without remapping the internal RAM? The code is now located so. If yes, what causes it to start from reset to the start of code at 0x00300000?

The evaluation board remaps the ROM starting from 0x01000000 and off-chip RAM starting at 0x02000000. The internal RAM is always remapped starting at zero. An AT91M40400 has 4 kbytes, AT91M40800 has 8 kbytes and AT91R40008 has

256 kbytes of internal RAM. If you have any kind of monitor connection to the board, you can read the EBI registers to verify.

The effect you're seeing may be due to the fact that the assembly language version is actually position-independent and it runs even in an unintended location, but the C version needs the *real* execution location.

HTH

Tauno Voipio tauno voipio @ iki fi

Reply to
Tauno Voipio

OT: Sorry for everybody waiting personal e-mail from me: the ISP is having problems with the SMTP server and I cannot get anything out that way.

TV

Reply to
Tauno Voipio
  1. Here is the assembly language disassembly. It works. ==================================================

test.elf: file format elf32-littlearm

Disassembly of section .text:

00300000 : 300000: ea000006 b 300020 300004: eafffffe b 300004 300008: eafffffe b 300008 30000c: eafffffe b 30000c 300010: eafffffe b 300010 300014: eafffffe b 300014 300018: eafffffe b 300018 30001c: eafffffe b 30001c

00300020 : 300020: e59f4058 ldr r4, [pc, #88] ; 300080

300024: e59f5058 ldr r5, [pc, #88] ; 300084 300028: e3a06801 mov r6, #65536 ; 0x10000

0030002c : 30002c: e5846000 str r6, [r4] 300030: e59f0068 ldr r0, [pc, #104] ; 3000a0

300034: e3a01000 mov r1, #0 ; 0x0

00300038 : 300038: e2400001 sub r0, r0, #1 ; 0x1 30003c: e1500001 cmp r0, r1 300040: 1afffffc bne 300038 300044: e5856000 str r6, [r5] 300048: e59f0050 ldr r0, [pc, #80] ; 3000a0

0030004c : 30004c: e2400001 sub r0, r0, #1 ; 0x1 300050: e1500001 cmp r0, r1 300054: 1afffffc bne 30004c 300058: eafffff3 b 30002c

0030005c : 30005c: ffff0000 swinv 0x00ff0000

00300060 : 300060: ffff0004 swinv 0x00ff0004

00300064 : 300064: ffff0008 swinv 0x00ff0008

00300068 : 300068: ffff0010 swinv 0x00ff0010

0030006c : 30006c: ffff0014 swinv 0x00ff0014

00300070 : 300070: ffff0018 swinv 0x00ff0018

00300074 : 300074: ffff0020 swinv 0x00ff0020

00300078 : 300078: ffff0024 swinv 0x00ff0024

0030007c : 30007c: ffff0028 swinv 0x00ff0028

00300080 : 300080: ffff0030 swinv 0x00ff0030

00300084 : 300084: ffff0034 swinv 0x00ff0034

00300088 : 300088: ffff0038 swinv 0x00ff0038

0030008c : 30008c: ffff003c swinv 0x00ff003c

00300090 : 300090: ffff0040 swinv 0x00ff0040

00300094 : 300094: ffff0044 swinv 0x00ff0044

00300098 : 300098: ffff0048 swinv 0x00ff0048

0030009c : 30009c: ffff004c swinv 0x00ff004c

003000a0 : 3000a0: 00200000 eoreq r0, r0, r0 Disassembly of section .data:

  1. Here is perhaps why gdb-6.0 doesn't work: =======================================

This is from:

formatting link

arm-*-*

GDB's ARM target, in 6.0, has not been updated to use the new frame mechanism.

Fortunatly the ARM target, in the GDB's mainline sources, has been updated so people encountering problems should consider downloading a more current GDB

formatting link

William

Reply to
William Wuister

"Tauno Voipio" wrote in news:QRKlb.47$ snipped-for-privacy@read3.inet.fi:

It is a *requirement* of the C language to clear .bss (well not so literally, C just expects all static and file scoped vars. to be zeroed if not given some other explicit initial value - .bss is an implementation of how one might do this) so don't skip this step lest some other "bad" programmer depend upon it. If you care about your image size then define every non-stack var. as .bss instead of .data. E.g.

int foo;

is better than

int s_foo = 0;

since the former takes no space in the image.

--
- Mark ->
--
Reply to
Mark A. Odell

Hi Tauno,

FYI:

[...]

The context of this code is that it's taken from an intermediate step showing the evolution from:

  • asm-only simple LED blinker (RAM startup)
  • initializing the basics of the C runtime and blinking the LED in C (RAM startup)
  • moving to ROM startup
  • initializing a C environment including static data (ROM startup)

The RAM startup versions ride on the assumption that Angel already set the port for output; this assumption is described in the accompanying text.

Also, the reasons above indicate why I put those comments in; yes, the vector table is meaningless for the RAM-startup application, but it is later moved into a ROM-startup application, and I wanted to keep the differences between those two pieces of code to an absolute minimum, so that the /important/ differences would stand out more clearly.

Reply to
Lewin A.R.W. Edwards

Please note that there are *no* constants pointing to the code or RAM data areas. The addressing to the constants is pc-relative, so it's by definition position-independent. The same applies to the branches (and calls in C code): they are position-independent by hardware.

In the code generated for C, there are pointer constants to data areas, which are *not* position-independent.

If you're running the code under Angel, check the location of the RAM area and correct the linker script to match. Angel *does* remap the chip selects very early on start-up. The chip select setup / remap code is quite similar to the code I presented some time ago in this group.

By the way: I'd address the PIO with one base address only and point to the different PIO registers with offset addressing from the base register.

formatting link

Aha, thank you. Nice to know.

GDB 5.13 works with code from GCC 3.2.1. The problem with remote debugging on AT91's is that the default set-up on GDB needs hardware breakpoints, but the hardware breakpoint unit in AT91 is accessible via the JTAG interface only, so GDB has to be changed to use software breakpoints instead.

HTH

Tauno Voipio tauno voipio @ iki fi

Reply to
Tauno Voipio

cancel

to

LED

to

There was nothing about it in the code snippet I saw.

Agreed - please do not take it as an insult.

Yes - it seems that William is running his code in a location different from the location it was linked into.

Can you please explain the method used to run RAM-based code. I still suspect that the RAM is at 0x02000000 or zero, but not at 0x00300000.

Keep up the good work! It's nice that somebody has the time and energy to make a book.

Regards, Tauno tauno voipio @ iki fi

Reply to
Tauno Voipio

Hi Tauno,

Right, right. I'm not insulted, aggrieved, or upset in any way! :) I was just monitoring the thread, and interjected to point out that there was method in my apparent madness, but this method wasn't obviously apparent from the tiny snippet posted (without its accompanying description text).

There are two RAM areas, as you know... For the RAM startup programs I assume Angel put the 512K external SRAM at 0x02000000, and that's where I emit the code segment. For ROM-startup programs I emit code to 0, and I assume no remapping (since the code runs from POR!), so data and bss go to

0x00300000.

I -think- William may be mixing and matching linker scripts and code sections from different projects in the book. Not sure. I need to look closer at what he wrote :)

Thanks. I've received a lot of positive feedback on the book, which is inspiring me to work harder on the sequels :)

(My ambition is to someday be famous enough to bitterly regret some grandiose generalization I made in a public forum, as in "640K is enough for anybody", "There may someday be a market for ten or twenty computers", etc).

--

-- Lewin A.R.W. Edwards

formatting link
Learn how to develop high-end embedded systems on a tight budget!
formatting link

Reply to
Lewin A.R.W. Edwards

for

etc).

Unless you live in the newspeak country of George Orwell, forecasting is always bloody difficult, especially forecasting the future - don't sweat, it's only ones and zeroes.

Tauno Voipio tauno voipio @ iki fi

Reply to
Tauno Voipio

Tauno,

I've been work>Please note that there are *no* constants pointing to the code or RAM data

are you refering to these 3 words?

stack_pointer: .word _stack_top bss_start: .word __bss_start__ bss_end: .word __bss_end__

If so, I'm still not sure what part of the C disassembly is wrong. I guess that I need to do something to the linker script, but I don't know what. Here's the linker script again:

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__ = . ; _stack_bottom = . ; . += 0x800 ; _stack_top = . ; }

end = .; _end = .; __end__ = .;

/* Symbols */ .stab 0 (NOLOAD) : { [ .stab ] }

.stabstr 0 (NOLOAD) : { [ .stabstr ] } }

Second question: =================

Since I can't get the gdb / cygwin combo to work, I was thinking about getting one of those "wiggler" devices. If I get that, what software on the pc (win2k) do you need to use it? Any free software?

thanks, William

Reply to
William Wuister

data

definition

Yes - it makes the startup address memory at 0x00300000 onward, but if the startup is with Angel, the RAM is not anymore there - the internal RAM is at

0x00000000 and the external RAM is at 0x02000000 if it's the same way as the other EB models. Your both programs seem to be located incorrectly, but the assembly language piece does work, as it happens to be position-independent.

This line ^^^^^ should be

sram: org = 0x02000000, len = 256K /* len can be also written as

0x00040000, of course */

Please check the evaluation board documentation where the usable RAM area is and set the definition to match.

What happens?

The Angel protocol seems to be more fragile than the others, so I quickly abandoned it in favour of GDB own remote protocol. Still, I made it work, just by following the instructions.

IIRC, the default ARM protocol in GDB was not set up for Angel, so there is a little editing needed to set the selection properly before compiling GDB. Also, GDB was set up to use the hardware beakpoints, which are not accessible via the AT91 serial interface. The only access to the ARM built-in hardware debug interface is via JTAG ('wiggler').

At least there was an active project to interface GDB with the Wiggler, but I don't know if it's ready yet.

HTH

Tauno tauno voipio @ iki fi

Reply to
Tauno Voipio

The C version works now. I made no changes to the code that wasn't working. After communicating with Atmel, I learned that bincom is buggy especially with win2k. They said to try ebload to load the binary file into SRAM. I did that and the LED is blinking! Beware of bincom.

Here is the final C version with boot.s: ================================

Environment: win2k, cygwin

BOOT.S:

--------------

.section .text .code 32 .globl vectors

@---------------------------------------------------------------------------- @ 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). @----------------------------------------------------------------------------

vectors: b reset @ Reset b . @ Undefined instruction b . @ SWI b . @ Prefetch abort b . @ Data abort b . @ reserved vector b . @ irqs b . @ fast irqs

@---------------------------------------------------------------------------- @ Entry-point code

reset:

@ Begin by clearing out the .bss section

ldr r1, bss_start ldr r2, bss_end ldr r3, =0

clear_bss: cmp r1,r2 strne r3,[r1],#+4 bne clear_bss

ldr r13,stack_pointer @ Initialize the stack pointer

bl main

b vectors

@----------------------------------------------------------------------------

@ Miscellaneous constants

stack_pointer: .word _stack_top bss_start: .word __bss_start__ bss_end: .word __bss_end__

.end

MAIN.C:

--------------

#define PIO_SODR 0xffff0030 #define PIO_CODR 0xffff0034

#define RED_LED 0x00010000 #define TIMEOUT 0x00200000

/* Quick and dirty macros to write a register or memory location word, halfword or byte */

#define WRITEREGW(addr,value) *((volatile unsigned int *) (addr)) = (value) #define WRITEREGH(addr,value) *((volatile unsigned short *) (addr)) = (value) #define WRITEREGB(addr,value) *((volatile unsigned char *) (addr)) = (value)

int main(void) { register int i;

while (1) { for (i=TIMEOUT; i>0; i--) { }

WRITEREGW(PIO_SODR, RED_LED); // turn on led

for (i=TIMEOUT; i>0; i--) { }

WRITEREGW(PIO_CODR, RED_LED); // turn off led }

}

MAKEFILE:

------------------

CFLAGS = -g -I. -mcpu=arm7tdmi ASFLAGS = -mcpu=arm7tdmi -gstabs LDFLAGS = -Teb40a-ram.ld -nostartfiles -Lgcc -L. OBJS = boot.o main.o EXE = test.elf OBJCOPYFLAGS = -O binary BIN = test.bin DIS = test.lst

$(BIN): $(EXE) arm-elf-objcopy $(OBJCOPYFLAGS) $(EXE) $(BIN) arm-elf-objdump -D $(EXE) >$(DIS) size $(EXE)

$(EXE): $(OBJS) arm-elf-gcc $(LDFLAGS) -o $(EXE) $(OBJS)

%.o:%.c arm-elf-gcc -c $(CFLAGS) $< -o $@

%.o:%.s arm-elf-as $(ASFLAGS) $< -o $@

clean: rm -f $(OBJS) rm -f $(EXE) rm -f $(BIN) rm -f $(DIS)

LINKER SCRIPT:

---------------------------

ENTRY(vectors)

SEARCH_DIR(.)

/* There is a single memory segment, representing the 256K on-board SRAM. */

MEMORY { sram : org = 0x00000100, len = 256K /* 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 = .; } > sram

.bss ADDR(.data) + SIZEOF(.data) : { __bss_start__ = . ; *(.bss); *(COMMON) __bss_end__ = . ; _stack_bottom = . ; . += 0x800 ; _stack_top = . ; } > sram

end = .; _end = .; __end__ = .;

/* Symbols */ .stab 0 (NOLOAD) : { [ .stab ] }

.stabstr 0 (NOLOAD) : { [ .stabstr ] } }

NOW ON TO JTAG.....

-----------------------------------

Reply to
William Wuister

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.