Issue with Open source for AT91SAM7s

I recently picked up a SAM7 kit (

http://www.sparkfun.com/commerce/produc … cts_id=774) with the Omlimex Jtag programer.

I’ve been following the document “Using Open Source Tools - Guide by Jim Lynch”

It took a bit of doing, to get everything working… bit it is now. When I try to copy main.bin to the SAM7 I get an error:

Info: configuration.c:50 configuration_output_handler(): failed writing file main.bin to flash bank 0 at offset 0x00000000

Info: configuration.c:50 configuration_output_handler(): destination is out of flash bank (offset and/or file too large)

Warning: arm7_9_common.c:685 arm7_9_assert_reset(): srst resets test logic, too

In the document the demo code compiles into a 4K file.

when I compile the code I get a 2 Meg file. Given my device has 256K of memory… I can see how this error is happening.

What I don’t understand is why.

Why is when I compile the same code is mine 2 Megs, instead of 4k

What can I do about it?

My guess is it’s some of the included libs, like libc.a is 2 megs.

Has anyone else had this issue.

What can be done to get a Blinky_LED “hello world” code running on the SAM7.

Thank you

This program for an LPC2103 uses 1.5k code space and 0.1k of RAM:

/*
** led.c
**
** simple program to test switch input and LED output
*/


#include <targets/LPC210x.h>

void LED_on();
void LED_off();

#define LED_ROW     0x04000000  //P0.26
#define LED_COLUMN  0x00000008  //P0.3
#define SWITCH_PIN 15           // Button 1

void
delay(int d)
{    
  for(; d; --d);
}



int main(void)
{
  int sw_state;

  while(1)
  {
    if (IOPIN & (1<<SWITCH_PIN)) 
      LED_on();
    else 
      LED_off();
  }
}

void LED_on()
{
  IODIR = 0x00000000;
  IODIR |= (LED_ROW | LED_COLUMN);
  IOSET = LED_ROW;    // row low
  IOSET = LED_COLUMN; // column high
}

void LED_off()
{
  IODIR = 0x00000000;
  IODIR |= (LED_ROW | LED_COLUMN);
  IOCLR = LED_ROW;    // row low  
  IOCLR = LED_COLUMN; // column high
}

You are probably including some libraries.

Leon

dcrackel:
Why is when I compile the same code is mine 2 Megs, instead of 4k

What can I do about it?

Thank you

What type of file is it? You can’t compare file size directly with actual program size, as the data usually isn’t in a RAW format.

What does arm-none-eabi-size say the size is? (might be arm-elf-size depending on how your toolchain is built).

Are you linking correctly for your specific processor? If your flash offset is wrong then you will also get this error.

What exactly is your blink demo code?

leon_heller:
This program for an LPC2103 uses 1.5k code space and 0.1k of RAM:

/*

** led.c
**
** simple program to test switch input and LED output
*/

#include <targets/LPC210x.h>

void LED_on();
void LED_off();

#define LED_ROW 0x04000000 //P0.26
#define LED_COLUMN 0x00000008 //P0.3
#define SWITCH_PIN 15 // Button 1

void
delay(int d)
{
for(; d; --d);
}

int main(void)
{
int sw_state;

while(1)
{
if (IOPIN & (1<<SWITCH_PIN))
LED_on();
else
LED_off();
}
}

void LED_on()
{
IODIR = 0x00000000;
IODIR |= (LED_ROW | LED_COLUMN);
IOSET = LED_ROW; // row low
IOSET = LED_COLUMN; // column high
}

void LED_off()
{
IODIR = 0x00000000;
IODIR |= (LED_ROW | LED_COLUMN);
IOCLR = LED_ROW; // row low
IOCLR = LED_COLUMN; // column high
}




You are probably including some libraries.



Leon

I set up a new C project to give your code a whirl, only I’m missing LPC210x.h

Could you include that also please.

Thank you

It’s part of the CrossWorks compiler. You will need the equivalent file for your compiler.

Leon

Nor is it correct for your SAM7 device.

Have you tried anything I have suggested?

theatrus:
What type of file is it? You can’t compare file size directly with actual program size, as the data usually isn’t in a RAW format.

What does arm-none-eabi-size say the size is? (might be arm-elf-size depending on how your toolchain is built).

Are you linking correctly for your specific processor? If your flash offset is wrong then you will also get this error.

What exactly is your blink demo code?

I’m pretty new to building code this way, Is it for the correct processor? I’m not sure… I’ll include my makefile (that came with the sparkfun document posted above)

Flash offset? I did use the setting in the doc that said you should the 1st time to remove bits that block flashing?

mww 0xffffff64 0x5a000004 # clear lock bit 0

mww 0xffffff64 0x5a002004 # clear lock bit 1

in script.ocd

What does arm-none-eabi-size say the size is? I’m using the yagarto tool chain.

I’m not really sure how to use the tool… it doesn’t like .bin’s.

C:\workspace\demo_at91sam7_blink_flash>arm-elf-size *.o

text data bss dec hex filename

304 0 4 308 134 blinker.o

348 0 0 348 15c crt.o

688 0 0 688 2b0 isrsupport.o

308 0 0 308 134 lowlevelinit.o

780 60 16 856 358 main.o

180 0 4 184 b8 timerisr.o

188 0 0 188 bc timersetup.o

There is actually far more code than I expected to do such a simple thing, as blink the LED. Here is the main.c

//  *****************************************************************************
//   						main.c
// 
//     Demonstration program for Atmel AT91SAM7S256-EK Evaluation Board
//
//     blinks LED0 (pin PA0) with an endless loop
//     blinks LED1 (pin PA1) using timer0 interrupt (200 msec rate)
//	   switch SW1 (PA19) triggers FIQ interrupt, turns on LED2 (Pin PA2)
//     plenty of variables for debugger practice
//
//  Author:  James P Lynch  May 12, 2007
//  *****************************************************************************
 
//  *******************************************************
//                Header Files
//  *******************************************************
#include "AT91SAM7S256.h"
#include "board.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"

//  *******************************************************
//                Function Prototypes
//  *******************************************************
void Timer0IrqHandler(void);
void FiqHandler(void);

//  *******************************************************
//                External References
//  *******************************************************
extern	void LowLevelInit(void);
extern	void TimerSetup(void);
extern	unsigned enableIRQ(void);
extern	unsigned enableFIQ(void);

//  *******************************************************
//               Global Variables
//  *******************************************************
unsigned int	FiqCount = 0;		// global uninitialized variable		
int				q;					// global uninitialized variable
int				r;					// global uninitialized variable
int				s;					// global uninitialized variable
int				m = 2;				// global initialized variable
int				n = 3;				// global initialized variable
int				o = 6;				// global initialized variable

struct comms {
	int		nBytes;
	char	*pBuf;
	char	Buffer[32];
}  Channel = {5, &Channel.Buffer[0], {"Faster than a speeding bullet"}};

int	main (void) {
	
	// lots of variables for debugging practice
	int				a, b, c;							// uninitialized variables
	char			d;									// uninitialized variable
	int				w = 1;								// initialized variable
	int				k = 2;								// initialized variable
	static long		x = 5;								// static initialized variable
	static char		y = 0x04;							// static initialized variable
	const char		*pText = "The rain in Spain";		// initialized string pointer variable
	struct EntryLock {									// initialized structure variable
		long		Key;
		int			nAccesses;
		char		Name[17];
	}  Access = {14705, 0, "Sophie Marceau"};		
	unsigned long	j;									// loop counter (stack variable)
	unsigned long	IdleCount = 0;						// idle loop blink counter (2x)
	int				*p;									// pointer to 32-bit word
	typedef void 	(*FnPtr)(void);						// create a "pointer to function" type
	FnPtr 			pFnPtr;								// pointer to a function
	double			x5;									// variable to test library function
	double			y5 = -172.451;						// variable to test library function
	const char 		DigitBuffer[] = "16383";			// variable to test library function
	long			n;									// variable to test library function
	
	// Initialize the Atmel AT91SAM7S256 (watchdog, PLL clock, default interrupts, etc.)
	LowLevelInit();
	

	// enable the Timer0 peripheral clock
	volatile AT91PS_PMC	pPMC = AT91C_BASE_PMC;			// pointer to PMC data structure
	pPMC->PMC_PCER = (1<<AT91C_ID_TC0);					// enable Timer0 peripheral clock


	// Set up the LEDs (PA0 - PA3)
	volatile AT91PS_PIO	pPIO = AT91C_BASE_PIOA;			// pointer to PIO data structure
	pPIO->PIO_PER = LED_MASK | SW1_MASK;				// PIO Enable Register - allow PIO to control pins P0 - P3 and pin 19
	pPIO->PIO_OER = LED_MASK;							// PIO Output Enable Register - sets pins P0 - P3 to outputs
	pPIO->PIO_SODR = LED_MASK;							// PIO Set Output Data Register - turns off the four LEDs
	

	// Select PA19 (pushbutton) to be FIQ function (Peripheral B)
	pPIO->PIO_BSR = SW1_MASK;
	

	// Set up the AIC  registers for Timer 0  
	volatile AT91PS_AIC	pAIC = AT91C_BASE_AIC;			// pointer to AIC data structure
	pAIC->AIC_IDCR = (1<<AT91C_ID_TC0);					// Disable timer 0 interrupt in AIC Interrupt Disable Command Register			
	pAIC->AIC_SVR[AT91C_ID_TC0] =						// Set the TC0 IRQ handler address in AIC Source 
    	(unsigned int)Timer0IrqHandler;        			// Vector Register[12]
	pAIC->AIC_SMR[AT91C_ID_TC0] =						// Set the interrupt source type and priority 
   		(AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 0x4 ); 		// in AIC Source Mode Register[12]
	pAIC->AIC_ICCR = (1<<AT91C_ID_TC0); 				// Clear the TC0 interrupt in AIC Interrupt Clear Command Register
	pAIC->AIC_IDCR = (0<<AT91C_ID_TC0);					// Remove disable timer 0 interrupt in AIC Interrupt Disable Command Reg			
	pAIC->AIC_IECR = (1<<AT91C_ID_TC0); 				// Enable the TC0 interrupt in AIC Interrupt Enable Command Register
	
	// Set up the AIC registers for FIQ (pushbutton SW1)
	pAIC->AIC_IDCR = (1<<AT91C_ID_FIQ);					// Disable FIQ interrupt in AIC Interrupt Disable Command Register			
	pAIC->AIC_SMR[AT91C_ID_FIQ] =						// Set the interrupt source type in AIC Source 
    	(AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE);  		// Mode Register[0]
	pAIC->AIC_ICCR = (1<<AT91C_ID_FIQ); 				// Clear the FIQ interrupt in AIC Interrupt Clear Command Register
	pAIC->AIC_IDCR = (0<<AT91C_ID_FIQ);					// Remove disable FIQ interrupt in AIC Interrupt Disable Command Register			
	pAIC->AIC_IECR = (1<<AT91C_ID_FIQ); 				// Enable the FIQ interrupt in AIC Interrupt Enable Command Register
	

	// Three functions from the libraries
	a = strlen(pText);									// strlen( ) returns length of a string
	x5 = fabs(y5);										// fabs( ) returns absolute value of a double
	n = atol(DigitBuffer);								// atol( ) converts string to a long
	

	// Setup timer0 to generate a 10 msec periodic interrupt
	TimerSetup();

	// enable interrupts
	enableIRQ();
	enableFIQ();

	// endless blink loop
	while (1) {
		if  ((pPIO->PIO_ODSR & LED1) == LED1)			// read previous state of LED1
			pPIO->PIO_CODR = LED1;						// turn LED1 (DS1) on	
		else
			pPIO->PIO_SODR = LED1;						// turn LED1 (DS1) off
		
		for (j = 1000000; j != 0; j-- );				// wait 1 second 1000000
	
		IdleCount++;									// count # of times through the idle loop
		pPIO->PIO_SODR = LED3;							// turn LED3 (DS3) off
											
		// uncomment following four lines to cause a data abort(3 blink code)
		//if  (IdleCount >= 10) {						// let it blink 5 times then crash
		//	p = (int *)0x800000;						// this address doesn't exist
		//	*p = 1234;									// attempt to write data to invalid address
		//}
		
		// uncomment following four lines to cause a prefetch abort (two blinks)
		//if  (IdleCount >= 10) {						// let it blink 5 times then crash
		//	pFnPtr = (FnPtr)0x800000;					// this address doesn't exist
		//	pFnPtr();									// attempt to call a function at a illegal address
		//}
	}
}

Make file

# ***************************************************************
# *     Makefile for Atmel AT91SAM7S256 - flash execution       *
# *                                                             *
# *                                                             *
# *   James P Lynch  May 12, 2007                               *
# ***************************************************************

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


# 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) libc.a libm.a 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
	

# **********************************************************************************************
#                            FLASH PROGRAMMING                                         
#
# Alternate make target for flash programming only
#
# You must create a special Eclipse make target (program) to run this part of the makefile 
# (Project -> Create Make Target...  then set the Target Name and Make Target to "program")
#
# OpenOCD is run in "batch" mode with a special configuration file and a script file containing
# the flash commands. When flash programming completes, OpenOCD terminates.
#
# Note that the script file of flash commands (script.ocd) is part of the project
#
# Programmers: Martin Thomas, Joseph M Dupre, James P Lynch
# **********************************************************************************************

# specify output filename here (must be *.bin file)
TARGET = main.bin

# specify the directory where openocd executable and configuration files reside
OPENOCD_DIR = 'c:/Program Files/openocd-2007re141/bin/'

# specify OpenOCD executable (pp is for the wiggler, ftd2xx is for the USB debuggers)
#OPENOCD = $(OPENOCD_DIR)openocd-pp.exe
OPENOCD = $(OPENOCD_DIR)openocd-ftd2xx.exe

# specify OpenOCD configuration file (pick the one for your device)
#OPENOCD_CFG = $(OPENOCD_DIR)at91sam7s256-wiggler-flash-program.cfg
#OPENOCD_CFG = $(OPENOCD_DIR)at91sam7s256-jtagkey-flash-program.cfg
OPENOCD_CFG = $(OPENOCD_DIR)at91sam7s256-armusbocd-flash-program.cfg

# program the AT91SAM7S256 internal flash memory
program: $(TARGET)
	@echo "Flash Programming with OpenOCD..."			# display a message on the console
	$(OPENOCD) -f $(OPENOCD_CFG)						# program the onchip FLASH here
	@echo "Flash Programming Finished."					# display a message on the console

I found a .bin on Sparkfun’s page copied that to the device and it works, at least I know the hardware is functional. It’s just an issue getting things to compile.

Take a glance through the .map file that gets generated, and also try running arm-elf-size on the main.out file (which should be an ELF file and therefore examinable using ‘size’). The map file should tell you what bits of code are getting placed at what addresses. (This is controlled mostly by the demo_at91sam7_blink_flash.cmd linker script.)

My guess is that the .bin file starts at address 0, but your code is being loaded at the beginning of the FLASH memory which starts at address 0x00100000.