Yahoo Groups archive

Lpc2000

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

Message

Re: Non-aligned access? - and bug in FreeRTOS LPC2106 GCC port

2006-01-25 by Guillermo Prandi

OK, mine was a mewbie mistake. I FORGOT TO READ the FreeRTOS LPC2xxx 
port notes, and therefore I missed the importance of starting/ending 
every ISR function that might perform a task switch (e.g., via 
xQueueSendFromISR) with the portENTER_SWITCHING_ISR() / 
portEXIT_SWITCHING_ISR() pair of macros. I also started my project 
from a WinARM demo example instead of a FreeRTOS example. Shame on me.

On the other hand, someone might find interesting that after 
correcting this I bumped into this bug in the FreeRTOS LPC2106 GCC 
port that seems to show up *sometimes* with GCC 4.01. There's already 
a patch available and it will be fixed in the next release of 
FreeRTOS. Read the thread here:

http://sourceforge.net/forum/message.php?msg_id=3537580

Guille


--- In lpc2000@yahoogroups.com, "Guillermo Prandi" 
<yahoo.messenger@m...> wrote:
>
> 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.