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]
> >
>Message
Re: Non-aligned access? - and bug in FreeRTOS LPC2106 GCC port
2006-01-25 by Guillermo Prandi
Attachments
- No local attachments were found for this message.