Yahoo Groups archive

Lpc2000

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

Message

Re: Non-aligned access?

2006-01-22 by Guillermo Prandi

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]
>

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.