Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: GNU inline assembler return value

2005-07-13 by brendanmurphy37

Hi,

Below is a simple startup sequence that fills the stack areas and 
initialises overall state, before jumping to 'C'.

Please don't bother pointing out there are more efficient ways of 
doing this: I know there are. It gets the job done....

Note that this is designed to work with a GNU link file which 
reserves the space for the stacks as follows:

/* next section is .bss, which is uninitialised data */
.bss : 
{
 __start_bss = . ;

/* include all uninitialised writable data */

 *(.bss)

/* include ramaining uninitialised data */

 *(COMMON)

 __end_bss = . ;

/* required allignment for stacks */

. =  ALIGN(0x10) ;

/* allocate room for supervisor stack */

 __tos_svc = . ;

 . += 0x800 ;

 __stack_svc = . ;

 /* allocate room for interrupt stack */

 __tos_irq = . ;

 . += 0x200 ;

 __stack_irq = . ;

/* allocate room for fast interrupt stack */

 __tos_fiq = . ;

  . += 0x100 ;

 __stack_fiq = . ;

} > ram

Hope this of some use to people.

Regards
Brendan

/* define values to use to zap stacks */

SVC_STACK_VALUE	= 0xaaaaaaaa
IRQ_STACK_VALUE	= 0xbbbbbbbb
FIQ_STACK_VALUE	= 0xcccccccc

/*
 * Exception vector table, common to all ARM-based systems 
 *
 * See ARM Architecture Reference Manual, Programmer's Model section 
for
 * details. Table entries just jump to handlers (using full 32-bit 
addressing)
 */

_int_vectors:	
	
ldr		pc, do_reset_addr
ldr		pc, do_reset_addr
ldr		pc, do_reset_addr
ldr		pc, do_reset_addr
ldr		pc, do_reset_addr
nop
ldr		pc, do_reset_addr
ldr		pc, do_reset_addr

/* table of interrupt handler adresses */

do_reset_addr:	.long	do_reset

/*
 * System reset handler
 */

do_reset:

/*
 * Set stack pointers for all modes used (supervisor, IRQ and FIQ)
 */

msr	cpsr_c, #0xd3	 /* ensure we're in supervisor mode */
ldr	sp, =__stack_svc /* set supervisor mode stack pointer */

msr	cpsr_c, #0xd2	 /* enter IRQ mode, with interrupts disabled 
*/
ldr	sp, =__stack_irq /* set IRQ mode stack pointer */

msr	cpsr_c, #0xd1	 /* enter FIQ mode, with interrupts disabled 
*/
ldr	sp, =__stack_fiq /* set FIQ mode stack pointer */

/* now zap all stacks with distinctive pattern, to help detect 
overflow */

ldr	r0, =__tos_svc		
ldr	r1, =__stack_svc
ldr	r2, =SVC_STACK_VALUE
bl	zap_mem

ldr	r0, =__tos_irq		
ldr	r1, =__stack_irq
ldr	r2, =IRQ_STACK_VALUE
bl	zap_mem

ldr	r0, =__tos_fiq		
ldr	r1, =__stack_fiq
ldr	r2, =FIQ_STACK_VALUE
bl	zap_mem

/*
 * Enable interrupts, enter supervisor mode and branch to start
 * of 'C' code
 */

msr	cpsr_c, #0xc3		/* I=1 F=1 T=0 MODE=supervisor */
b	main

/*
 * Function to zap a block of memory with specified value
 * Note that block MUST be word alligned
 *
 * r0: start of block
 * r1: end of block
 * r2: value to load
 * lr: return address
 */

zap_mem:

	cmp		r0, r1
	strlo	r2, [r0], #4
	blo		zap_mem 
	mov		pc, lr



--- In lpc2000@yahoogroups.com, "xjag74" <detlef.weidner@w...> wrote:
> All right, thank you Charles and Brendan (parallel replies),
> if that's the usual way then I'll code test pattern writing before 
> RAM copying in the startup.s file.
> 
> Regards
> xjag
> 
> --- In lpc2000@yahoogroups.com, "xjag74" <detlef.weidner@w...> 
wrote:
> > Now I realized that the interrupts use another stack (IRQ stack) 
> than 
> > a normal routine (User stack).
> > 
> > Is it possible to read the User stack pointer within the ISR?
> > 
> > What I try to do is to capture the SP every timer1 ISR entry 
> (200us) 
> > and to store the maximum value to figure out if the stack 
collides 
> > with the data area.
> > 
> > The stack check option of the GNU compiler is not working.
> > 
> > Regards
> > xjag
> > 
> > 
> > 
> >

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.