Thanks, Daniel. In my case I am not using nested interrupts, and my
stacks are pretty generous (LPC2138=32K RAM). That's why I am
puzzled. I am using FreeRTOS/GCC4.0.1. This is an excerpt of my
startup code:
--------------------------------------------------
// Stack Sizes
.set UND_STACK_SIZE, 0x00000040
.set ABT_STACK_SIZE, 0x00000040
.set FIQ_STACK_SIZE, 0x00000040
.set IRQ_STACK_SIZE, 0x00000400
.set SVC_STACK_SIZE, 0x00000400
// Initialize Interrupt System
// - Set stack location for each mode
// - Leave in Supervisor Mode with Interrupts Disabled
// -----------------------------------------------
ldr r0,=_stack // 0x40008000 minus 32 bytes for IAP.
msr CPSR_c,#MODE_UND|I_BIT|F_BIT
mov sp,r0
sub r0,r0,#UND_STACK_SIZE
msr CPSR_c,#MODE_ABT|I_BIT|F_BIT
mov sp,r0
sub r0,r0,#ABT_STACK_SIZE
msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT
mov sp,r0
sub r0,r0,#FIQ_STACK_SIZE
msr CPSR_c,#MODE_IRQ|I_BIT
mov sp,r0
sub r0,r0,#IRQ_STACK_SIZE
msr CPSR_c,#MODE_SVC|I_BIT|F_BIT
mov sp,r0
sub r0,r0,#SVC_STACK_SIZE
msr CPSR_c,#MODE_SYS|I_BIT|F_BIT
mov sp,r0
// (This is from FreeRTOS)
// We want to start in supervisor mode.
// Operation will switch to system
// mode when the first task starts.
msr CPSR_c,#MODE_SVC|I_BIT|F_BIT
// Initialization and startup follows
....
--------------------------------------------------
FIQs are not a concern; I use them as a "specialized" reset button
via EINT3 (it does little more than reset). They are not normally
triggered.
I even added a check before each interrupt routine. Check it out:
#define INTERRUPT_CHECK \
{ register int _sp asm("sp"); \
asm volatile ("mov r0,#0x40000000" ); \
asm volatile ("orr r0,r0,#0x000000e0" ); \
asm volatile ("orr r0,r0,#0x00007f00" ); \
asm volatile ("cmp r0,sp" ); \
asm volatile ("blo 0f" ); \
asm volatile ("sub r0,r0,#0x00000100" ); \
asm volatile ("cmp r0,sp" ); \
asm volatile ("blo 1f" ); \
asm volatile ("0:" ); \
error_n1("OUT OF STACK!",_sp); \
asm volatile ("1:" ); \
}
void MyFunc(void) __attribute__ ((interrupt("IRQ")));
void MyFunc(void)
{
INTERRUPT_CHECK
/* my code here */
}
The IRQ stack should be below 0x40007fe0 and is 512 bytes long. The
error function enters a safe-mode (IRQs disabled, initializes
hardware, outputs given string or "bad pointer" if problems with the
string). The error_n1() function has been tested several times in
other circumstances and it works like a charm (for instance, it is
called from the pabt, dabt and undf handlers which DO trigger!).
The stack check from above never fires (except when I tamper with the
values just to verify that it WOULD trigger). On the other hand, I
keep getting undf, dabt and pabt everywhere (i.e., r15 pointing to
RAM or some weird location) when I start using any SPI interrupt
routine. I rewritten my program several times, tried many ways, but
every time the SPI interrupt service routine starts executing, I get
a crash sooner or later (within 10 seconds is a good average). This
doesn't happen with my other interrupt routines, like my two UARTs or
the OS timer tick. They work fine. I just don't know what to check
next. Sometimes the problem doesn't show up for hours if I compile
with no optimization (-O0) and sometimes it seems to work a little
longer if I set the processor to run at 10x5 MHz (I usually run it at
10x1 MHz). The system crashed with IRQ routines as simple as this:
static void dummySPIIRQ(void) __attribute__ ((interrupt("IRQ")));
static void dummySPIIRQ(void)
{
tdSPI++;
if( S0SPSR & S0SPSR_SPIF )
{
IOSET0 = PIN7BIT; // Remove /CS from target SPI device
short rddata = S0SPDR;
tdSPIRDY = (0xffff & (int) rddata) | 0x80000000;
}
S0SPINT = 0x01;
VICVectAddr = 0x00000000;
}
To worsen things even more, I don't have a JTAG connector on my
board. Any suggestions will be greately appreciated.
Guille
--- In lpc2000@yahoogroups.com, "Daniel Gelbgras"
<daniel.gelbgras@e...> wrote:
>
> Hi,
>
> My guess is that you may want to increase
> the (normal) interrupt stack *size*
> and FIQ interrupt stack *size*
> in your cpu startup (initialization) file
>
> For example in Keil startup.s file, these constants are
> IRQ_Stack_Size and USR_Stack_Size
>
>
> (When you use only a single interrupt, either FIQ or normal
interrupt,
> it is working because there is some allocated stack space,
> but I suppose that one of these 2 constants is too small,
> so you use the same memory space for both isr's
>
> If you enable both interrupts together,
> one isr can corrupt the register values saved by the other
isr,
> and the program crashes after a variable amount of time)
>
> HTH
> kind regards
> daniel
> ----- Original Message -----
> From: Guillermo Prandi
> To: lpc2000@yahoogroups.com
> Sent: Saturday, January 21, 2006 10:34 PM
> Subject: [lpc2000] Re: Non-aligned access?
>
>
> Gary, I wonder if you could solve your problem. I am facing the
same
> problem here too. :(
>
> Guille
>
> --- In lpc2000@yahoogroups.com, "ee_gary" <ee_gary@y...> wrote:
> >
> > Definitely seems interrupt related... When I disable the timer
> > interrupt, the interrupt driven spi works great. When I
disable the
> > spi interrupt, the interrupt driven timer works great. When
both
> are
> > enabled, I get about 10 seconds of run time and then the
program
> runs
> > off into the bushes. I'm using Keil w/ GCC, ARM-mode. What's
> > special about having two interrupts active that might cause
this?
> >
> > Thanks,
> >
> > Gary
> >
> > --- In lpc2000@yahoogroups.com, Tom Walsh <tom@o...> wrote:
> > >
> > > Charles Manning wrote:
> > >
> > > >On Wednesday 09 November 2005 11:13, Guillermo Prandi wrote:
> > > >
> > > >
> > > >>Just an idea: perhaps interrupt routines are not
> saving/restoring all
> > > >>the registers correctly?
> > > >>
> > > >>
> > > >
> > > >That would be my first though too.
> > > >
> > > >Either that or a stack corruption causing the register to be
> nuked,
> > but that
> > > >would probably be less likely.
> > > >
> > > >Is 40000241H within the RAM address space? If not, what does
it
> > correspond to?
> > > >
> > > >If you can figure out how R1 got to have this value you're
well
> on
> > your way to
> > > >solving the problem.
> > > >
> > > >
> > > >
> > > >
> > > >
> > >
> > > I had that, I grapped some project source of an example
program
> and
> > used
> > > that as the foundation for my project. I got bit by
> an "__attribute__
> > > ((naked))" definition of an ISR handler.
> > >
> > > TomW
> > >
> > > >
> > > >
> > > >>Guille
> > > >>
> > > >>--- In lpc2000@yahoogroups.com, "ee_gary" <ee_gary@y...>
wrote:
> > > >>
> > > >>
> > > >>>--- In lpc2000@yahoogroups.com, Charles Manning
> <manningc2@a...>
> > > >>>
> > > >>>
> > > >>wrote:
> > > >>
> > > >>
> > > >>>>On Tuesday 08 November 2005 14:40, Tom Walsh wrote:
> > > >>>>
> > > >>>>
> > > >>>>>ee_gary wrote:
> > > >>>>>
> > > >>>>>
> > > >>>>>>Hello,
> > > >>>>>>
> > > >>>>>>I'm having a problem where my code goes into the bushes
> after
> > > >>>>>>
> > > >>>>>>
> > > >>~10
> > > >>
> > > >>
> > > >>
> > > >>>>>>seconds. Running it in the simulator results in a "Non-
> aligned
> > > >>>>>>Access" error, ARM Instruction at 00000200H, Memory
Access
> at
> > > >>>>>>40000241H. Any idea what that means? Simple code,
just an
> > > >>>>>>
> > > >>>>>>
> > > >>interrupt
> > > >>
> > > >>
> > > >>
> > > >>>>>>driven timer and interrupt driven SPI.
> > > >>>>>>
> > > >>>>>>
> > > >>>>What instruction was this accessing?
> > > >>>>
> > > >>>>
> > > >>>The instruction at 200H was:
> > > >>>LDR R3,[R1]
> > > >>>
> > > >>>It was part of this function:
> > > >>>void wait (void) {
> > > >>> unsigned long i;
> > > >>>
> > > >>> i = timeval;
> > > >>> while ((i + 10) != timeval);
> > > >>>}
> > > >>>
> > > >>>where 'timeval' is incremented by an ISR.
> > > >>>
> > > >>>
> > > >>>
> > > >>>>The following things can give you non-aligned accesses:
> > > >>>>
> > > >>>>1) Trying to read a U32 on a non-4-byte boundary or a U16
on a
> > > >>>>
> > > >>>>
> > > >>>non-2byte
> > > >>>
> > > >>>
> > > >>>
> > > >>>>boundary. This might raise a data abort.
> > > >>>>
> > > >>>>2) Trying to execute an ARM instruction at a non-4-byte
> location
> > > >>>>
> > > >>>>
> > > >>or
> > > >>
> > > >>
> > > >>
> > > >>>a thumb
> > > >>>
> > > >>>
> > > >>>
> > > >>>>instruction at a non-2-byte location. This might raise a
> prefetch
> > > >>>>
> > > >>>>
> > > >>abort.
> > > >>
> > > >>
> > > >>
> > > >>>>>You can run into this when mixing Thumb with ARM code.
When
> > > >>>>>
> > > >>>>>
> > > >>interrupt
> > > >>
> > > >>
> > > >>
> > > >>>>>routines are entered, the processor is in ARM mode,
either
> > > >>>>>
> > > >>>>>
> > > >>write your
> > > >>
> > > >>
> > > >>
> > > >>>>>handlers in ARM or switch to THUMB mode, process the
> interrupt,
> > > >>>>>
> > > >>>>>
> > > >>then
> > > >>
> > > >>
> > > >>
> > > >>>>>exit THUMB mode and return from interrupt.
> > > >>>>>
> > > >>>>>
> > > >>>>Yes, this is possible since thumb addresses are marked by
> setting
> > > >>>>
> > > >>>>
> > > >>>the least
> > > >>>
> > > >>>
> > > >>>
> > > >>>>significant bit. If you try executing the address by
using a
> > > >>>>
> > > >>>>
> > > >>>regular branch
> > > >>>
> > > >>>
> > > >>>
> > > >>>>or bl then this will break. You need to use a bx.
> > > >>>>
> > > >>>>
> > > >>>>
> > > >>>>>FWIW, Thumb, and thumb-internetworking, is too much
trouble
> to
> > > >>>>>
> > > >>>>>
> > > >>deal
> > > >>
> > > >>
> > > >>
> > > >>>>>with, I run strictly ARM mode.
> > > >>>>>
> > > >>>>>
> > > >>>>To each their own, but I strongly disagree. I use thumb
and
> > > >>>>
> > > >>>>
> > > >>>interworking a
> > > >>>
> > > >>>
> > > >>>
> > > >>>>lot. gcc support for this is great.
> > > >>>>
> > > >>>>I always write all my assembly with interworking (ie
using bx)
> > > >>>>
> > > >>>>
> > > >>>regardless.
> > > >>>
> > > >>>I'm using all ARM code, with the interworking option
enabled
> in the
> > > >>>compiler/linker.
> > > >>>
> > > >>>
> > > >>>
> > > >>>>For an example you might look at the example stuff I
posted
> on the
> > > >>>>
> > > >>>>
> > > >>>AT91SAM7
> > > >>>
> > > >>>
> > > >>>
> > > >>>>group.
> > > >>>>
> > > >>>>
> > > >>
> > > >>Yahoo! Groups Links
> > > >>
> > > >>
> > > >>
> > > >>
> > > >>
> > > >
> > > >
> > > >
> > > >
> > > >Yahoo! Groups Links
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > >
> > >
> > > --
> > > Tom Walsh - WN3L - Embedded Systems Consultant
> > > http://openhardware.net, http://cyberiansoftware.com
> > > "Windows? No thanks, I have work to do..."
> > > ----------------------------------------------------
> > >
> >
>
>
>
>
>
>
> SPONSORED LINKS Microcontrollers Microprocessor Intel
microprocessors
> Pic microcontrollers
>
>
> --------------------------------------------------------------------
----------
> YAHOO! GROUPS LINKS
>
> a.. Visit your group "lpc2000" on the web.
>
> b.. To unsubscribe from this group, send an email to:
> lpc2000-unsubscribe@yahoogroups.com
>
> c.. Your use of Yahoo! Groups is subject to the Yahoo! Terms
of Service.
>
>
> --------------------------------------------------------------------
----------
>
>
>
> [Non-text portions of this message have been removed]
>Message
Re: Non-aligned access?
2006-01-22 by Guillermo Prandi
Attachments
- No local attachments were found for this message.