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
> >
> >
> >
> >Message
Re: GNU inline assembler return value
2005-07-13 by brendanmurphy37
Attachments
- No local attachments were found for this message.