Forums

Re: lpc2129 Stack pointer problem

Started by Robert Adsett November 5, 2004
At 06:11 PM 11/5/04 +0000, you wrote:

>hello,
>
>I have a problem the interrupt only work for 16 interrupts, and at 16
>it crash!! if I change the __STACK_SIZE_IRQ__ = 0x100; to
>__STACK_SIZE_IRQ__ = 0x200; (on lpc2119.ld) will crash at 32
>interrupts, anyone can help me!!

Ah Ha! Definitely an important indication. >I use gnuarm3.4.1 for linux, LPC2129 and I use the following
>functions for enter and exit in interrupt:
>
>#define ISR_ENTRADA() asm volatile(" sub r14, r14, #4\n" \
> " stmfd r13!, {r0-r3, r12, r14}\n"
>\
> " mrs r0, spsr\n" \
> " stmfd r13!, {r0}")
>#define ISR_SAIDA() asm volatile(" mrs r0, cpsr\n" \
> " orr r0, r0, #0xC0\n" \
> " msr cpsr_c, r0\n" \
> " ldmfd r13!, {r0}\n" \
> " msr spsr_cxsf, r0 \n"\
> " ldmfd r13!, {r0-r3, r12, PC}^")
>
>and the following code:

Compare to the assembly support from the newlib-lpc interrupt support

/**************************** interrupt.inc *******************************/
/* Copyright 2004/07/05 Aeolus Development */
/* All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions */
/* are met: */
/* 1. Redistributions of source code must retain the above copyright */
/* notice, this list of conditions and the following disclaimer. */
/* 2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the*/
/* documentation and/or other materials provided with the */
/* distribution. */
/* 3. The name of the Aeolus Development or its contributors may not be */
/* used to endorse or promote products derived from this software */
/* without specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE AEOULUS DEVELOPMENT "AS IS" AND ANY */
/* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */
/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AEOLUS DEVELOPMENT BE */
/* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */
/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */
/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */
/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,*/
/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE */
/* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/* Provides support for interrupt routines. */
/************************************************************************/
/*
* TLIB revision history:
* 1 interrupt.inc 13-Jul-2004,14:02:38,`RADSETT' Original archive version
* TLIB revision history ends.
*/ /********************* InterruptEntry ***********************************/
/* InterruptEntry -- Macro to encapsulate the setup needed at the */
/* start of an interrupt. Use as a companion to InterruptExit. */
/* Will save sufficient registers so that is a call is made to a */
/* standard function enough has been saved that no registers will be */
/* corrupted on interrupt return. Any registers beyond r0-r3, and r12 */
/* that will be used must be saved explicitly. Interrupts are left as */
/* they were (IE if this is an IRQ, IRQs will be disabled and the FIQ */
/* will be in the state it was when the interrupt occured.). */
.macro InterruptEntry
sub r14, r14, #4 /* Get the correct return */
/* address. */
stmfd r13!, {r0-r3, r12, r14} /* Save the register that can */
/* be lost during a procedure */
/* call. */
mrs r0, spsr /* Get the status register of */
/* the interrupted code and */
stmfd r13!, {r0} /* save it. */
.endm

********************* InterruptExit ************************************/
/* InterruptExit -- Macro to encapsulate the teardown needed at the */
/* end of an interrupt. Use as a companion to InterruptEntry. */
/* Disables interrupts, then restores the registers and the processor */
/* state saved by InterruptEntry before returning to the interrupted */
/* program. */
.macro InterruptExit
mrs r0, cpsr /* Disable interrupts. */
orr r0, r0, #0xC0
msr cpsr_c, r0

ldmfd r13!, {r0} /* Get the interrupted */
/* processor state from the */
/* stack and restore it. */
msr spsr_cxsf, r0

ldmfd r13!, {r0-r3, r12, PC}^ /* Restore the registers saved */
/* by InterruptEntry and return */
/* to the interrupted program */
/* restoring the processor's */
/* status register. */
.endm >...
>VICVectAddr5 = (u32)captura;
>....
>
>void captura(void){
> ISR_ENTRADA();

I think this is your problem. I expect that the compiler has already
modified the stack by the time the macro gets executed. Because you only
restore back to where the compiler inserted it the stack keeps growing. You
need to do the shell in assembly not in C (in-line assembly is not the same).

The simplest way to confirm or deny my suspicions is to dump the assembler
from the compiler as I earlier suggested and see what is happening. If
this is indeed the problem check out the uart interrupt support in the
newb-lpc for an example of an assembly shell. It should be independent of
everything else in there and it is not difficult. Only a few lines would
need to change to use different service routines (just function names really).

This is one reason I never (well almost never) use in-line assembly. The
compiler is quite free to mess it up it your own best interests! Robert

" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "

Kelvin Throop, III


An Engineer's Guide to the LPC2100 Series

At 09:19 PM 11/5/04 +0000, you wrote:
>Hi Robert,
>
>Finally, this works!!!
>
>You had right!!!
>
>Thank you very much....

Great, thanks for letting us know.

Robert

" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "

Kelvin Throop, III


hello,

I have a problem the interrupt only work for 16 interrupts, and at 16
it crash!! if I change the __STACK_SIZE_IRQ__ = 0x100; to
__STACK_SIZE_IRQ__ = 0x200; (on lpc2119.ld) will crash at 32
interrupts, anyone can help me!!

I use gnuarm3.4.1 for linux, LPC2129 and I use the following
functions for enter and exit in interrupt:

#define ISR_ENTRADA() asm volatile(" sub r14, r14, #4\n" \
" stmfd r13!, {r0-r3, r12, r14}\n"
\
" mrs r0, spsr\n" \
" stmfd r13!, {r0}")
#define ISR_SAIDA() asm volatile(" mrs r0, cpsr\n" \
" orr r0, r0, #0xC0\n" \
" msr cpsr_c, r0\n" \
" ldmfd r13!, {r0}\n" \
" msr spsr_cxsf, r0 \n"\
" ldmfd r13!, {r0-r3, r12, PC}^")

and the following code:

...
VICVectAddr5 = (u32)captura;
....

void captura(void){
ISR_ENTRADA(); escreve_UART0("EI");
if(T1IR & TIR_MR0I){

T1IR |= TIR_MR0I;
Timer1OverflowCount++;

}else if(T1IR & TIR_CR0I){

T1IR |= TIR_CR0I;
escreve_UART0("1"); }else if(T1IR & TIR_CR1I){

T1IR |= TIR_CR1I;
escreve_UART0("2");
}

VICSoftIntClr = (1<<VIC_TIMER1);
VICVectAddr = 0x00000000;
escreve_UART0("SI\n");
ISR_SAIDA();
}

I think the problem can be on ISR_ENTRADA(); and ISR_SAIDA(); because
do not decrement the stack pointer what do you think?

regards,
Domingos Bento
_________________________________________________________
CEAC Cursos de formao profissional - pe informaes aqui.:
http://ceac.online.pt/



Hi Robert,

Finally, this works!!!

You had right!!!

Thank you very much.... Best Regards
Domingos Bento
_________________________________________________________
CEAC Cursos de formao profissional - pe informaes aqui.:
http://ceac.online.pt/