Yahoo Groups archive

Lpc2000

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

Message

Re: [lpc2000] lpc2129 Stack pointer problem

2004-11-05 by Robert Adsett

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

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.