How to modify the linker for do "ram fuctions" AT9

Hello, im using Yagarto and a AT91SAM7S-EK Board (256kb flash chip).

I was following the “Using Open Source Tools for AT91SAM7S” document, and it does not explain how to modify the linker for write some fuctions to the RAM, for handle interrupts (with a FlashProgram).

As i see in another sites, i included this define:

#define RAMFUNC attribute ((long_call, section (“.ramsection”)))

The “.ramsection” have to be inside the linker file, but i dont know where i have to include it, and what modifications i have to do (if i have to do it).

The file is the same which is included with the Tutorial, here it is:

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

/* specify the AT91SAM7S256 memory areas  */
MEMORY 
{
	flash	: ORIGIN = 0,          LENGTH = 256K	/* FLASH EPROM		*/	
	ram		: ORIGIN = 0x00200000, LENGTH = 64K  	/* static RAM area	*/
}


/* define a global symbol _stack_end  (see analysis in annotation above) */
_stack_end = 0x20FFFC;

/* now define the output sections  */
SECTIONS 
{
	. = 0;								/* set location counter to address zero  */
	
	.text :								/* collect all sections that should go into FLASH after startup  */ 
	{
		*(.text)						/* all .text sections (code)  */
		*(.rodata)						/* all .rodata sections (constants, strings, etc.)  */
		*(.rodata*)						/* all .rodata* sections (constants, strings, etc.)  */
		*(.glue_7)						/* all .glue_7 sections  (no idea what these are) */
		*(.glue_7t)						/* all .glue_7t sections (no idea what these are) */
		_etext = .;						/* define a global symbol _etext just after the last code byte */
	} >flash							/* put all the above into FLASH */

	.data :								/* collect all initialized .data sections that go into RAM  */ 
	{
		_data = .;						/* create a global symbol marking the start of the .data section  */
		*(.data)						/* all .data sections  */
		_edata = .;  					/* define a global symbol marking the end of the .data section  */
										
	} >ram AT >flash          			/* put all the above into RAM (but load the LMA initializer copy into FLASH)  */

	.bss :								/* collect all uninitialized .bss sections that go into RAM  */
	{
		_bss_start = .;					/* define a global symbol marking the start of the .bss section */
		*(.bss)							/* all .bss sections  */
	} >ram								/* put all the above in RAM (it will be cleared in the startup code */

	. = ALIGN(4);						/* advance location counter to the next 32-bit boundary */
	_bss_end = . ;						/* define a global symbol marking the end of the .bss section */
}
	_end = .;							/* define a global symbol marking the end of application RAM */

I tried to included it after (*.data), but it does not work (crash!).

What i have to do?

Thx very much.

AFAIK, it should just work when adding a

*(.ramsection)

line after the

*(.data)

line.

I do something very similar in a hobby project and it works as expected, I’ll look it up tonight.

Perhaps the crash you see is caused by something else.

How does it crash? does it reset, or hang, or give data aborts?

Hi,

Check Martin Thomas’s website. Tons of infos and examples. And exactly what you want to do, written for LPC, but easily portable.

Thanks to him, my start in the ARM world was very easy :smiley:

Here is the link for the ram function example:

http://www.siwawi.arubi.uni-kl.de/avr_p … cc_ramfunc

Angelo

Thx very much for your answers.

Angelo, from this project was where i copied the idea xD

Yeah it worked, adding ramsection line after the data line… hehe my fault, i was typing “ramfunc” instead “ramsection” in the link file ¬¬’, you know the computer does that you type, not that you desire hehe.

Guys, I have tried all this and am having trouble. My ram function works from the debugger but crashes the system in stand alone. If it makes any difference my startup code leaves the chip is SYS mode for the application code. My hardware is an Atmel AT91SAM7S-EK board with a 256K part mounted.

I use the following:

#define RAMFUNC attribute ((long_call, section (“.Rtext”)))

RAMFUNC uint32 FlashBurnStoredCycles(void)

/*

// This function exists and executes from RAM. It is used to burn a copy

// of StoredCycles[y] into the FLASH memory at page 1023 (*(0x0003ff00))

//

// Receives: void

//

// Returns: void

*/

{

uint8 f, x, y; // array indexes

uint32 buf; // 32 bit temp buffer

uint32 *FlashLastPage; // pointer to last page of FLASH

uint32 fct;

// initialize the FLASH pointer to last page start

FlashLastPage = (uint32 *) 0x0003ff00;

f = y = 0; // init indexes

for(x = 0; x < 10; x++)

{

buf = StoredCycles[y++];

buf |= (StoredCycles[y++] << 16);

FlashLastPage[f++] = buf;

buf = StoredCycles[y];

FlashLastPage[f++] = buf;

y = 0;

}

fct = 0x20000;

while(!(MC_FSR & MC_FRDY) && fct > 0)

–fct;

if(fct = 0)

return 0;

MC_FCR = (((0x5a << 24) | 1023 << 8) | MC_FCMD_START_PROG);

fct = 0x20000;

while(!(MC_FSR & MC_FRDY) && fct > 0)

–fct;

if(fct = 0)

return 0;

if(MC_FSR & (MC_LOCKE | MC_PROGE))

return 0;

return 1;

}

here is my linker command file:

SECTIONS

{

. = 0; /* set location counter to address zero */

.text : /* collect all sections that should go into FLASH after startup */

{

(.text) / all .text sections (code) */

(.rodata) / all .rodata sections (constants, strings, etc.) */

(.rodata) /* all .rodata* sections (constants, strings, etc.) */

(.glue_7) / all .glue_7 sections (no idea what these are) */

(.glue_7t) / all .glue_7t sections (no idea what these are) */

_etext = .; /* define a global symbol _etext just after the last code byte */

} >flash /* put all the above into FLASH */

.data : /* collect all initialized .data sections that go into RAM */

{

_data = .; /* create a global symbol marking the start of the .data section */

(.data) / all .data sections */

*(.Rtext)

_edata = .; /* define a global symbol marking the end of the .data section */

} >ram AT >flash /* put all the above into RAM (but load the LMA initializer copy into FLASH) */

.bss : /* collect all uninitialized .bss sections that go into RAM */

{

_bss_start = .; /* define a global symbol marking the start of the .bss section */

(.bss) / all .bss sections */

} >ram /* put all the above in RAM (it will be cleared in the startup code */

. = ALIGN(4); /* advance location counter to the next 32-bit boundary */

_bss_end = . ; /* define a global symbol marking the end of the .bss section */

}

_end = .; /* define a global symbol marking the end of application RAM */

PROVIDE(end = .);

noether:
Thx very much for your answers.

Angelo, from this project was where i copied the idea xD

Yeah it worked, adding ramsection line after the data line… hehe my fault, i was typing “ramfunc” instead “ramsection” in the link file ¬¬’, you know the computer does that you type, not that you desire hehe.

Are you sure the crash is caused by running from RAM or could it simply be the function itself that misbehaves?

Maybe the timeout is reached more quickly when running from RAM than when running from flash (because the code executes faster).

There seems to be a bug in your C code: when comparing a variable you usually use == (double =) instead of = (single =).

Also why do you have y as a variable? it’s being reset in each loop iteration.

Yes, Thanks for looking at it. I overlooked that I only had ‘=’ instead of ‘==’ in two if() statements. I have fixed those without success. I posted my code because I knew it was very possible that the function was missbehaving. I am new to ARM. The code does not really crash. It does write the FLASH correctly but then causes a Data Abort exception and I am not sure why.

y is correctly reset to zero through each itteration of the for loop. The for() statement uses x not y.

bertrik:
Are you sure the crash is caused by running from RAM or could it simply be the function itself that misbehaves?

Maybe the timeout is reached more quickly when running from RAM than when running from flash (because the code executes faster).

There seems to be a bug in your C code: when comparing a variable you usually use == (double =) instead of = (single =).

Also why do you have y as a variable? it’s being reset in each loop iteration.