EmbDev.net

Forum: ARM programming with GCC/GNU tools Sample Code - Please help!


von David S. (davy)


Rate this post
useful
not useful
Hi,

While I have worked with atmega and pic18f micros before I have recently
had to start work on an AT91SAM7S256 on an olimex development board. I
started using Jim Lynchs' tutorial to set up my ARM-USB-OCD and the
eclipse development environment with the Yagarto toolchain. I could get
the sample code to compile and run in the flash of the micro.

The original plan was to simply build onto this code and add my own
routines (specifically uart and spi). I have been able to get some UART
code working although when I try my spi routines the debugger seems to
crash. I would ideally like some simple code to use as a foundation onto
which I can build my applications. I have found some useful code on the
site http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/
although I cannot seem to write a makefile to compile this code
correctly. I have tried modifying the makefile I got with Jim Lynchs
tutorial although I just seem to get endless errors. If someone has some
code with an included makefile which contains SPI or anything I would be
very grateful If I could get a copy.

Sorry for the long post and thanks in advance for your help!

David.

von James L. (lynchzilla)


Rate this post
useful
not useful
Hi David.

My makefile was designed to be simple and would thus only require
reading the first chapter in the Stallman Make User's Guide to fully
understand.

Adding a new C file is straightforward; you need to add the new file to
the list of objects and provide a compilation step at the bottom. Here's
my makefile with a new routine spi.c added.

# ***************************************************************
#      Makefile for Atmel AT91SAM7S256 - flash execution       
#                                                              
#                                                              
# * James P Lynch  September 3, 2006                            *
# ***************************************************************

NAME   = demo_at91sam7_blink_flash

# variables
CC      = arm-elf-gcc
LD      = arm-elf-ld -v
AR      = arm-elf-ar
AS      = arm-elf-as
CP      = arm-elf-objcopy
OD    = arm-elf-objdump

CFLAGS  = -I./ -c -fno-common -O3 -g
AFLAGS  = -ahls -mapcs-32 -o crt.o
LFLAGS  =  -Map main.map -Tdemo_at91sam7_blink_flash.cmd
CPFLAGS = --output-target=binary
ODFLAGS  = -x --syms

OBJECTS = crt.o  main.o timerisr.o timersetup.o isrsupport.o
lowlevelinit.o blinker.o blink.o wait.o spi.o


# make target called by Eclipse (Project -> Clean ...)
clean:
  -rm $(OBJECTS) crt.lst main.lst main.out main.bin main.hex main.map
main.dmp


#make target called by Eclipse  (Project -> Build Project)
all:  main.out
  @ echo "...copying"
  $(CP) $(CPFLAGS) main.out main.bin
  $(OD) $(ODFLAGS) main.out > main.dmp

main.out: $(OBJECTS) demo_at91sam7_blink_flash.cmd
  @ echo "..linking"
  $(LD) $(LFLAGS) -o main.out $(OBJECTS) libgcc.a

crt.o: crt.s
  @ echo ".assembling"
  $(AS) $(AFLAGS) crt.s > crt.lst

main.o: main.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) main.c

timerisr.o: timerisr.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) timerisr.c

lowlevelinit.o: lowlevelinit.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) lowlevelinit.c

timersetup.o: timersetup.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) timersetup.c

isrsupport.o: isrsupport.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) isrsupport.c

blinker.o: blinker.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) blinker.c

blink.o: blink.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) blink.c

wait.o: wait.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) wait.c

spi.o: spi.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) spi.c



Notice that I added the reference to spi.o to the list of objects, as
shown below:

OBJECTS = crt.o  main.o timerisr.o timersetup.o isrsupport.o
lowlevelinit.o blinker.o blink.o wait.o spi.o
                         -----


I also added a compilation step for the spi.c file to the bottom, as
shown below.

spi.o: spi.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) spi.c


If you are trying to use library routines in your added modules, make
sure that you add the libraries to your project and add them to the
linker command, for example the following linker command would include
the libc.a and libm.a libraries. Make sure libgcc.a is ALWAYS LAST!

  $(LD) $(LFLAGS) -o main.out $(OBJECTS) libc.a libm.a libgcc.a

May I suggest that you take my original sample application, which you
succeeded in getting to run, and add just a single new source file with
some simple but legal C language statements in it and see if it can
compile and build. Prove to yourself that you can add a simple source
file before attempting to port more sophisticated routines from other
sources.

Cheers,
Jim Lynch

von David S. (davy)


Rate this post
useful
not useful
Thanks for your help Jim.

I added the extra files as per the above instructions. I basically took
the atmel spi routines and added them to the spi.c file with slight
modifications. While I have yet to test this with my hardware I am able
to compile and step through all the code in eclipse without incidence.
Next I added some Uart routines. Using an oscilloscope I could confirm
these are working great with the hardware.

After running the code for a couple of time I now seem to be having
trouble. I can run through the code and using my oscilloscope I can see
UART is being output from within an infinite loop. Although after a few
seconds the codes goes into the blinker.c routine. I haven't always been
able to properly check which code although I believe its a pre fetch
abort error. What confuses me is why it can run through the code a
couple of times before this happens?

I tried to go through the code step by step although this error appears
to occur at random places in the code and doesn't seem to be consistent.

I have been running this code on a 7s256 using the .cmd file from your
example. I have changed the end of stack to "_stack_end = 0x7FFC;" for
the 128 although am unsure what to set the following lines to:
flash  : ORIGIN = 0,          LENGTH = 256K  /* FLASH EPROM    */
  ram    : ORIGIN = 0x00200000, LENGTH = 64K    /* static RAM area  */

I assume not having these set correctly won't exactly be helping my
problem but even when running it on the 256 I get the same issue.

I would appreciate it if you perhaps had any ideas as to why this is
occuring?

Thanking you in advance,

David.

von David S. (davy)


Rate this post
useful
not useful
Sorry I didn't make it to clear before but I have two boards, one is an
Olimex devlopment board with a AT91SAM7S256 on it. The other is a board
I have made using a AT91SAM7S128. Just as a sanity check I reloaded your
original unmodified code onto the olimex board. Works fine as expected.
Then I loaded it onto my 128 board and once again entered the blinker.c
file with code 3. I ran it again and this time code is showing as 88
'x', another time 16 '\020' (different every time).

With the problem occurring only on the 128 I assume it is just some
processor specific thing I have forgotten to change such as the
aforementioned .cmd modifications.

I am really stuck here :(

Thanks,

David.

von James L. (lynchzilla)


Rate this post
useful
not useful
Hi David.

The two CPUs have different memory layouts; this must be handled in the
linker command script (demo_at91sam7_blink_flash.cmd). You must alter
the flash and ram limits and correctly specify the end-of-stack location
(4 bytes from the end of RAM).

The example compiled and built for 256K of flash and 64k of RAM will NOT
execute on a 128k chip - the stack will be placed in non-existant RAM
and you will get a fault.

Modify the linker script to something like this:

/* identify the Entry Point  (_vec_reset is defined in file crt.s)  */
ENTRY(_vec_reset)

/* specify the at91sam7memory areas  */
MEMORY
{
   flash : ORIGIN = 0,          LENGTH = 128K  /* FLASH EPROM    */
   ram   : ORIGIN = 0x00200000, LENGTH = 32K    /* static RAM area  */
}


/* define a global symbol _stack_end  */
_stack_end = 0x207FFC;

/* now define the output sections  */
SECTIONS
 {
 . = 0;

 .text :
   {
     *(.text)
     *(.rodata)
     *(.rodata*)
     *(.glue_7)
     *(.glue_7t)
     _etext = .;
  } >flash

  .data :
    {
      _data = .;
      *(.data)
      _edata
    } >ram AT >flash

  .bss
    {
      _bss_start = .;
      *(.bss)
  } >ram

  . = ALIGN(4);
  _bss_end = .;
}
_end = .;


Cheers,
Jim Lynch

von David S. (davy)


Rate this post
useful
not useful
Thanks for your response. I have replied to your response in the
sparkfun forum too, thought I may as well reply in here as well in case
someone reading can offer me some help.

I tried the above values although I still have the same problem with the
code calling the blinker.c through interrupt. This code works fine on
the 256 processor. I thought that by changing those above values I was
fixing everything that needed to be done to run on the 128 version.
There must be something I am overlooking... I am 99% sure the hardware
itself is correct.

So if anyone can think of anything that may help please let me know. I
am getting desperate here!

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.