Yahoo Groups archive

Lpc2000

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

Thread

GCC compiler generates wrong code for interrupt handler routines

GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by c.barbaro

Hi,
I'm working with LCP2138 using the Keil demo board and the UVision IDE
with GNU compiler 3.3.1.
When I switched from examples to a little more complicated interrupt
handler for the UART0 I started experiencing strange problems: hangs,
reboots, function in the main program called out of order...
Giving a look to the asm listing I see that the GCC compiler insert an
extra 'sub lr, lr, #4' opcode in the isr entrypoint, and at the end of
isr uses the  'subs pc, lr, #4'
In this way the main program continues the execution not from were was
interrupted, but at an instruction before.
Here is the isr code and the partial assembler listing:

/**
 * Interrupt service routine for UART0 device
*/
void Uart0_isr(void)
{
        WORD rxnewend;
        BYTE IrqIdent;
        BYTE i, c;

        IrqIdent = U0IIR & 0x0F;
        switch(IrqIdent) {
          case 0x02: // Transmit holding register empty.
            IOSET1 = LED1;
            break;
          case 0x04: // RX Data available
            for(i=0;i<4;i++) {
              c = U0RBR;
              rxnewend = rxbufend+1;
              if(rxnewend >= RXBUFSIZE)
                rxnewend = 0;
              if(rxnewend == rxbufini) {
                // Buffer full
                ComStatus |= COM_FULL;
              }
              else {
                rxbuffer[rxbufend] = c;
                rxbufend = rxnewend;
              }
            }
            ComStatus &= ~COM_EMPTY;
            IOSET1 = LED2;
            break;
          case 0x06: // RX Line status Interrupt
            IOSET1 = LED3;
            i = U0LSR;
            break;
          case 0x0C: // Character time out
            c = U0RBR;
            rxnewend = rxbufend+1;
            if(rxnewend >= RXBUFSIZE)
              rxnewend = 0;
            if(rxnewend == rxbufini) {
              // Buffer full
              ComStatus |= COM_FULL;
            }
            else {
              rxbuffer[rxbufend] = c;
              rxbufend = rxnewend;
            }
            ComStatus &= ~COM_EMPTY;
            IOSET1 = LED4;
            break;
          default:
            IOSET1 = LED8;
            break;
        }
}


 241:**** /**
 242:****  * Interrupt service routine for UART0 device
 243:**** */
 244:**** void Uart0_isr(void)
 245:**** {
 459              		.loc 1 245 0
 460              		@ Interrupt Service Routine.
 461              		@ args = 0, pretend = 0, frame = 0
 462              		@ frame_needed = 0, uses_anonymous_args = 0
 463 03e4 04E04EE2 		sub	lr, lr, #4
 464 03e8 7F502DE9 		stmfd	sp!, {r0, r1, r2, r3, r4, r5, r6, ip, lr}
 465              	.LCFI8:
 248: **** 
 249: ****         WORD rxnewend;
 250: ****         BYTE IrqIdent;
 251: ****         BYTE i, c;
 252: **** 
 253: ****         IrqIdent = U0IIR & 0x0F;
 466              		.loc 1 253 0
 467              	.LBB6:
 468 03ec 0339A0E3 		mov	r3, #49152
 469 03f0 8E3283E2 		add	r3, r3, #-536870904
 470 03f4 0030D3E5 		ldrb	r3, [r3, #0]	@ zero_extendqisi2
 471 03f8 0F3003E2 		and	r3, r3, #15

......
......

 296: ****           default:
 297: ****             IOSET1 = LED8;
 609              		.loc 1 297 0
 610 059c 0E32A0E3 		mov	r3, #-536870912
 611 05a0 0A3983E2 		add	r3, r3, #163840
 612 05a4 143083E2 		add	r3, r3, #20
 613 05a8 0225A0E3 		mov	r2, #8388608
 614              	.L71:
 615 05ac 002083E5 		str	r2, [r3, #0]
 298: ****             break;
 299: ****         }
 300: **** 
 301: **** 
 302: **** }
 616              		.loc 1 302 0
 617              	.L50:
 618 05b0 7F50BDE8 		ldmfd	sp!, {r0, r1, r2, r3, r4, r5, r6, ip, lr}
 619 05b4 04F05EE2 		subs	pc, lr, #4

Note that if I slighty semplify the handler (ex. removing the for()
loop), the compiler needs to use less registers, don't save the LR
register, does not insert the sub lr,lr,#4 opcode and the code work!!
Anyone experienced similar problems and has a solution?
Thank you.

Re: [lpc2000] GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by 42Bastian Schick

c.barbaro <c.barbaro@...> schrieb am Tue, 31 Jan 2006 10:47:41 
-0000:

> Anyone experienced similar problems and has a solution?

I'd suggest to write the ISR wrapper in assembler and call from
there your ISR.
This allows you also to write the ISR in thumb mode.
This is also more compatible if you ever have to switch to another 
compiler and/or use an RTOS :-)

-- 
42Bastian Schick

Re: [lpc2000] GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by Richard Duits

I had the same problem and it disappeared when I disabled the "Support 
Calls between ARM and THUMB Instruction Set" option.
If you use THUMB code, you can place the interrupts in a separate source 
file. If you use THUMB code in your interrupts, then you should write a 
wrapper function in assembler.


Richard.



c.barbaro wrote:
Show quoted textHide quoted text
> Hi,
> I'm working with LCP2138 using the Keil demo board and the UVision IDE
> with GNU compiler 3.3.1.
> When I switched from examples to a little more complicated interrupt
> handler for the UART0 I started experiencing strange problems: hangs,
> reboots, function in the main program called out of order...
> Giving a look to the asm listing I see that the GCC compiler insert an
> extra 'sub lr, lr, #4' opcode in the isr entrypoint, and at the end of
> isr uses the  'subs pc, lr, #4'
> In this way the main program continues the execution not from were was
> interrupted, but at an instruction before.
> Here is the isr code and the partial assembler listing:
>
> /**
> * Interrupt service routine for UART0 device
> */
> void Uart0_isr(void)
> {
>         WORD rxnewend;
>         BYTE IrqIdent;
>         BYTE i, c;
>
>         IrqIdent = U0IIR & 0x0F;
>         switch(IrqIdent) {
>           case 0x02: // Transmit holding register empty.
>             IOSET1 = LED1;
>             break;
>           case 0x04: // RX Data available
>             for(i=0;i<4;i++) {
>               c = U0RBR;
>               rxnewend = rxbufend+1;
>               if(rxnewend >= RXBUFSIZE)
>                 rxnewend = 0;
>               if(rxnewend == rxbufini) {
>                 // Buffer full
>                 ComStatus |= COM_FULL;
>               }
>               else {
>                 rxbuffer[rxbufend] = c;
>                 rxbufend = rxnewend;
>               }
>             }
>             ComStatus &= ~COM_EMPTY;
>             IOSET1 = LED2;
>             break;
>           case 0x06: // RX Line status Interrupt
>             IOSET1 = LED3;
>             i = U0LSR;
>             break;
>           case 0x0C: // Character time out
>             c = U0RBR;
>             rxnewend = rxbufend+1;
>             if(rxnewend >= RXBUFSIZE)
>               rxnewend = 0;
>             if(rxnewend == rxbufini) {
>               // Buffer full
>               ComStatus |= COM_FULL;
>             }
>             else {
>               rxbuffer[rxbufend] = c;
>               rxbufend = rxnewend;
>             }
>             ComStatus &= ~COM_EMPTY;
>             IOSET1 = LED4;
>             break;
>           default:
>             IOSET1 = LED8;
>             break;
>         }
> }
>
>
> 241:**** /**
> 242:****  * Interrupt service routine for UART0 device
> 243:**** */
> 244:**** void Uart0_isr(void)
> 245:**** {
> 459                          .loc 1 245 0
> 460                          @ Interrupt Service Routine.
> 461                          @ args = 0, pretend = 0, frame = 0
> 462                          @ frame_needed = 0, uses_anonymous_args = 0
> 463 03e4 04E04EE2             sub      lr, lr, #4
> 464 03e8 7F502DE9             stmfd      sp!, {r0, r1, r2, r3, r4, r5, 
> r6, ip, lr}
> 465                    .LCFI8:
> 248: ****
> 249: ****         WORD rxnewend;
> 250: ****         BYTE IrqIdent;
> 251: ****         BYTE i, c;
> 252: ****
> 253: ****         IrqIdent = U0IIR & 0x0F;
> 466                          .loc 1 253 0
> 467                    .LBB6:
> 468 03ec 0339A0E3             mov      r3, #49152
> 469 03f0 8E3283E2             add      r3, r3, #-536870904
> 470 03f4 0030D3E5             ldrb      r3, [r3, #0]      @ 
> zero_extendqisi2
> 471 03f8 0F3003E2             and      r3, r3, #15
>
> ......
> ......
>
> 296: ****           default:
> 297: ****             IOSET1 = LED8;
> 609                          .loc 1 297 0
> 610 059c 0E32A0E3             mov      r3, #-536870912
> 611 05a0 0A3983E2             add      r3, r3, #163840
> 612 05a4 143083E2             add      r3, r3, #20
> 613 05a8 0225A0E3             mov      r2, #8388608
> 614                    .L71:
> 615 05ac 002083E5             str      r2, [r3, #0]
> 298: ****             break;
> 299: ****         }
> 300: ****
> 301: ****
> 302: **** }
> 616                          .loc 1 302 0
> 617                    .L50:
> 618 05b0 7F50BDE8             ldmfd      sp!, {r0, r1, r2, r3, r4, r5, 
> r6, ip, lr}
> 619 05b4 04F05EE2             subs      pc, lr, #4
>
> Note that if I slighty semplify the handler (ex. removing the for()
> loop), the compiler needs to use less registers, don't save the LR
> register, does not insert the sub lr,lr,#4 opcode and the code work!!
> Anyone experienced similar problems and has a solution?
> Thank you.
>
>
>
>
>
> SPONSORED LINKS
> Microcontrollers 
> <http://groups.yahoo.com/gads?t=ms&k=Microcontrollers&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s=95&.sig=mfaAujKZXA2Z_vxre9sGnQ> 
> 	Microprocessor 
> <http://groups.yahoo.com/gads?t=ms&k=Microprocessor&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s=95&.sig=9jjd2D3GOLIESVQssLmLsA> 
> 	Intel microprocessors 
> <http://groups.yahoo.com/gads?t=ms&k=Intel+microprocessors&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s=95&.sig=OMnZuqMZX95mgutt4B-tDw> 
>
> Pic microcontrollers 
> <http://groups.yahoo.com/gads?t=ms&k=Pic+microcontrollers&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s=95&.sig=Malspbd0T4Rq3M4Q0nHrfw> 
>
>
>
> ------------------------------------------------------------------------
> YAHOO! GROUPS LINKS
>
>     *  Visit your group "lpc2000
>       <http://groups.yahoo.com/group/lpc2000>" on the web.
>        
>     *  To unsubscribe from this group, send an email to:
>        lpc2000-unsubscribe@yahoogroups.com
>       <mailto:lpc2000-unsubscribe@yahoogroups.com?subject=Unsubscribe>
>        
>     *  Your use of Yahoo! Groups is subject to the Yahoo! Terms of
>       Service <http://docs.yahoo.com/info/terms/>.
>
>
> ------------------------------------------------------------------------
>

Re: GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by unity0724

Hi, Experienced similar problem before.
Got it fixed with moving all local variables to global variables.
(I also kept every C statement in the ISR to be simple, such that
it does not create own local variables on stack)
I think ver GCC 3.4 and onwards has that bug fixed.
Regards

--- In lpc2000@yahoogroups.com, "c.barbaro" <c.barbaro@4...> wrote:
>
> Hi,
> I'm working with LCP2138 using the Keil demo board and the UVision 
IDE
> with GNU compiler 3.3.1.
> When I switched from examples to a little more complicated 
interrupt
> handler for the UART0 I started experiencing strange problems: 
hangs,
> reboots, function in the main program called out of order...
> Giving a look to the asm listing I see that the GCC compiler 
insert an
> extra 'sub lr, lr, #4' opcode in the isr entrypoint, and at the 
end of
> isr uses the  'subs pc, lr, #4'
> In this way the main program continues the execution not from were 
was
> interrupted, but at an instruction before.
> Here is the isr code and the partial assembler listing:
> 
> /**
>  * Interrupt service routine for UART0 device
> */
> void Uart0_isr(void)
> {
>         WORD rxnewend;
>         BYTE IrqIdent;
>         BYTE i, c;
> 
>         IrqIdent = U0IIR & 0x0F;
>         switch(IrqIdent) {
>           case 0x02: // Transmit holding register empty.
>             IOSET1 = LED1;
>             break;
>           case 0x04: // RX Data available
>             for(i=0;i<4;i++) {
>               c = U0RBR;
>               rxnewend = rxbufend+1;
>               if(rxnewend >= RXBUFSIZE)
>                 rxnewend = 0;
>               if(rxnewend == rxbufini) {
>                 // Buffer full
>                 ComStatus |= COM_FULL;
>               }
>               else {
>                 rxbuffer[rxbufend] = c;
>                 rxbufend = rxnewend;
>               }
>             }
>             ComStatus &= ~COM_EMPTY;
>             IOSET1 = LED2;
>             break;
>           case 0x06: // RX Line status Interrupt
>             IOSET1 = LED3;
>             i = U0LSR;
>             break;
>           case 0x0C: // Character time out
>             c = U0RBR;
>             rxnewend = rxbufend+1;
>             if(rxnewend >= RXBUFSIZE)
>               rxnewend = 0;
>             if(rxnewend == rxbufini) {
>               // Buffer full
>               ComStatus |= COM_FULL;
>             }
>             else {
>               rxbuffer[rxbufend] = c;
>               rxbufend = rxnewend;
>             }
>             ComStatus &= ~COM_EMPTY;
>             IOSET1 = LED4;
>             break;
>           default:
>             IOSET1 = LED8;
>             break;
>         }
> }
> 
> 
>  241:**** /**
>  242:****  * Interrupt service routine for UART0 device
>  243:**** */
>  244:**** void Uart0_isr(void)
>  245:**** {
>  459              		.loc 1 245 0
>  460              		@ Interrupt Service Routine.
>  461              		@ args = 0, pretend = 0, frame = 0
>  462              		@ frame_needed = 0, 
uses_anonymous_args = 0
>  463 03e4 04E04EE2 		sub	lr, lr, #4
>  464 03e8 7F502DE9 		stmfd	sp!, {r0, r1, r2, r3, r4, 
r5, r6, ip, lr}
>  465              	.LCFI8:
>  248: **** 
>  249: ****         WORD rxnewend;
>  250: ****         BYTE IrqIdent;
>  251: ****         BYTE i, c;
>  252: **** 
>  253: ****         IrqIdent = U0IIR & 0x0F;
>  466              		.loc 1 253 0
>  467              	.LBB6:
>  468 03ec 0339A0E3 		mov	r3, #49152
>  469 03f0 8E3283E2 		add	r3, r3, #-536870904
>  470 03f4 0030D3E5 		ldrb	r3, [r3, #0]	@ 
zero_extendqisi2
>  471 03f8 0F3003E2 		and	r3, r3, #15
> 
> ......
> ......
> 
>  296: ****           default:
>  297: ****             IOSET1 = LED8;
>  609              		.loc 1 297 0
>  610 059c 0E32A0E3 		mov	r3, #-536870912
>  611 05a0 0A3983E2 		add	r3, r3, #163840
>  612 05a4 143083E2 		add	r3, r3, #20
>  613 05a8 0225A0E3 		mov	r2, #8388608
>  614              	.L71:
>  615 05ac 002083E5 		str	r2, [r3, #0]
>  298: ****             break;
>  299: ****         }
>  300: **** 
>  301: **** 
>  302: **** }
>  616              		.loc 1 302 0
>  617              	.L50:
>  618 05b0 7F50BDE8 		ldmfd	sp!, {r0, r1, r2, r3, r4, 
r5, r6, ip, lr}
>  619 05b4 04F05EE2 		subs	pc, lr, #4
> 
> Note that if I slighty semplify the handler (ex. removing the for()
> loop), the compiler needs to use less registers, don't save the LR
> register, does not insert the sub lr,lr,#4 opcode and the code 
work!!
Show quoted textHide quoted text
> Anyone experienced similar problems and has a solution?
> Thank you.
>

Re: GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by Karl Olsen

--- In lpc2000@yahoogroups.com, "unity0724" <unity0724@y...> wrote:
>
> Hi, Experienced similar problem before.
> Got it fixed with moving all local variables to global variables.
> (I also kept every C statement in the ISR to be simple, such that
> it does not create own local variables on stack)
> I think ver GCC 3.4 and onwards has that bug fixed.

That is right.  GCC 3.3.x and older generated incorrect entry/exit code 
for IRQ and FIQ handlers.  Use 3.4.x or newer.

Karl Olsen

Re: GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by c.barbaro

Thank you, I'll follow the suggestion since in the near future I want
to use nested interrupts that requires an asm wrapper anyway.
For now I patched the problem using an ISR that performs a call to the
real one that contains the code I need.

--- In lpc2000@yahoogroups.com, 42Bastian Schick <bastian42@m...> wrote:
Show quoted textHide quoted text
>
> c.barbaro <c.barbaro@4...> schrieb am Tue, 31 Jan 2006 10:47:41 
> -0000:
> 
> > Anyone experienced similar problems and has a solution?
> 
> I'd suggest to write the ISR wrapper in assembler and call from
> there your ISR.
> This allows you also to write the ISR in thumb mode.
> This is also more compatible if you ever have to switch to another 
> compiler and/or use an RTOS :-)
> 
> -- 
> 42Bastian Schick
>

Re: GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by c.barbaro

Thank you, I'll upgrade as soon as is possible even I I'll have to
renounce to the Keil uVision IDE.
Someone told me that is compatible only with GCC 3.3.1

Carlo Barbaro

--- In lpc2000@yahoogroups.com, "Karl Olsen" <kro@p...> wrote:
Show quoted textHide quoted text
>
> --- In lpc2000@yahoogroups.com, "unity0724" <unity0724@y...> wrote:
> >
> > Hi, Experienced similar problem before.
> > Got it fixed with moving all local variables to global variables.
> > (I also kept every C statement in the ISR to be simple, such that
> > it does not create own local variables on stack)
> > I think ver GCC 3.4 and onwards has that bug fixed.
> 
> That is right.  GCC 3.3.x and older generated incorrect entry/exit code 
> for IRQ and FIQ handlers.  Use 3.4.x or newer.
> 
> Karl Olsen
>

Re: [lpc2000] Re: GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by Richard Duits

Take a look at the following link:
http://www.keil.com/support/docs/3127.htm

Keil directed me to this page when I asked if I could use other GCC 
binaries. I did not try it myself yet.

Richard.


c.barbaro wrote:
Show quoted textHide quoted text
> Thank you, I'll upgrade as soon as is possible even I I'll have to
> renounce to the Keil uVision IDE.
> Someone told me that is compatible only with GCC 3.3.1
>
> Carlo Barbaro
>
> --- In lpc2000@yahoogroups.com, "Karl Olsen" <kro@p...> wrote:
> >
> > --- In lpc2000@yahoogroups.com, "unity0724" <unity0724@y...> wrote:
> > >
> > > Hi, Experienced similar problem before.
> > > Got it fixed with moving all local variables to global variables.
> > > (I also kept every C statement in the ISR to be simple, such that
> > > it does not create own local variables on stack)
> > > I think ver GCC 3.4 and onwards has that bug fixed.
> >
> > That is right.  GCC 3.3.x and older generated incorrect entry/exit code
> > for IRQ and FIQ handlers.  Use 3.4.x or newer.
> >
> > Karl Olsen
> >
>
>
>
>
>
>
> SPONSORED LINKS
> Microcontrollers 
> <http://groups.yahoo.com/gads?t=ms&k=Microcontrollers&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s=95&.sig=mfaAujKZXA2Z_vxre9sGnQ> 
> 	Microprocessor 
> <http://groups.yahoo.com/gads?t=ms&k=Microprocessor&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s=95&.sig=9jjd2D3GOLIESVQssLmLsA> 
> 	Intel microprocessors 
> <http://groups.yahoo.com/gads?t=ms&k=Intel+microprocessors&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s=95&.sig=OMnZuqMZX95mgutt4B-tDw> 
>
> Pic microcontrollers 
> <http://groups.yahoo.com/gads?t=ms&k=Pic+microcontrollers&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s=95&.sig=Malspbd0T4Rq3M4Q0nHrfw> 
>
>
>
> ------------------------------------------------------------------------
> YAHOO! GROUPS LINKS
>
>     *  Visit your group "lpc2000
>       <http://groups.yahoo.com/group/lpc2000>" on the web.
>        
>     *  To unsubscribe from this group, send an email to:
>        lpc2000-unsubscribe@yahoogroups.com
>       <mailto:lpc2000-unsubscribe@yahoogroups.com?subject=Unsubscribe>
>        
>     *  Your use of Yahoo! Groups is subject to the Yahoo! Terms of
>       Service <http://docs.yahoo.com/info/terms/>.
>
>
> ------------------------------------------------------------------------
>

Re: [lpc2000] Re: GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by Tom Walsh

Richard Duits wrote:

>Take a look at the following link:
>http://www.keil.com/support/docs/3127.htm
>
>Keil directed me to this page when I asked if I could use other GCC 
>binaries. I did not try it myself yet.
>
>  
>
Definately get away from using Thumb code with gcc-3.4.x.  There is some 
documented problems, under certain conditions, that  when an interrupt 
occurs during a Thumb function execution it can corrupt the stack.  This 
stack corruption was noted in gcc-3.3.x and was finally resolved in 
gcc-4.0.x.

I'm currently using gcc-4.0.2 and the thumb code is running fine under 
heavy interrupt usage.

Regards,

TomW

BTW, I'm not using the Keil thingy.

-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Re: [lpc2000] GCC compiler generates wrong code for interrupt handler routines

2006-01-31 by 3gpabko

I am also using GCC v3.3.1 integrated in Ashling IDE
and I don't have problems with the code generated for
ISR.
You should use:

__attribute__ ((interrupt("IRQ")))

or

__attribute__ ((interrupt("FIQ")))

for your ISR's.

Regards
Zdravko Dimitrov



--- "c.barbaro" <c.barbaro@...> wrote:

> Hi,
> I'm working with LCP2138 using the Keil demo board
> and the UVision IDE
> with GNU compiler 3.3.1.
> When I switched from examples to a little more
> complicated interrupt
> handler for the UART0 I started experiencing strange
> problems: hangs,
> reboots, function in the main program called out of
> order...
> Giving a look to the asm listing I see that the GCC
> compiler insert an
> extra 'sub lr, lr, #4' opcode in the isr entrypoint,
> and at the end of
> isr uses the  'subs pc, lr, #4'
> In this way the main program continues the execution
> not from were was
> interrupted, but at an instruction before.
> Here is the isr code and the partial assembler
> listing:
> 
> /**
>  * Interrupt service routine for UART0 device
> */
> void Uart0_isr(void)
> {
>         WORD rxnewend;
>         BYTE IrqIdent;
>         BYTE i, c;
> 
>         IrqIdent = U0IIR & 0x0F;
>         switch(IrqIdent) {
>           case 0x02: // Transmit holding register
> empty.
>             IOSET1 = LED1;
>             break;
>           case 0x04: // RX Data available
>             for(i=0;i<4;i++) {
>               c = U0RBR;
>               rxnewend = rxbufend+1;
>               if(rxnewend >= RXBUFSIZE)
>                 rxnewend = 0;
>               if(rxnewend == rxbufini) {
>                 // Buffer full
>                 ComStatus |= COM_FULL;
>               }
>               else {
>                 rxbuffer[rxbufend] = c;
>                 rxbufend = rxnewend;
>               }
>             }
>             ComStatus &= ~COM_EMPTY;
>             IOSET1 = LED2;
>             break;
>           case 0x06: // RX Line status Interrupt
>             IOSET1 = LED3;
>             i = U0LSR;
>             break;
>           case 0x0C: // Character time out
>             c = U0RBR;
>             rxnewend = rxbufend+1;
>             if(rxnewend >= RXBUFSIZE)
>               rxnewend = 0;
>             if(rxnewend == rxbufini) {
>               // Buffer full
>               ComStatus |= COM_FULL;
>             }
>             else {
>               rxbuffer[rxbufend] = c;
>               rxbufend = rxnewend;
>             }
>             ComStatus &= ~COM_EMPTY;
>             IOSET1 = LED4;
>             break;
>           default:
>             IOSET1 = LED8;
>             break;
>         }
> }
> 
> 
>  241:**** /**
>  242:****  * Interrupt service routine for UART0
> device
>  243:**** */
>  244:**** void Uart0_isr(void)
>  245:**** {
>  459              		.loc 1 245 0
>  460              		@ Interrupt Service Routine.
>  461              		@ args = 0, pretend = 0, frame =
> 0
>  462              		@ frame_needed = 0,
> uses_anonymous_args = 0
>  463 03e4 04E04EE2 		sub	lr, lr, #4
>  464 03e8 7F502DE9 		stmfd	sp!, {r0, r1, r2, r3, r4,
> r5, r6, ip, lr}
>  465              	.LCFI8:
>  248: **** 
>  249: ****         WORD rxnewend;
>  250: ****         BYTE IrqIdent;
>  251: ****         BYTE i, c;
>  252: **** 
>  253: ****         IrqIdent = U0IIR & 0x0F;
>  466              		.loc 1 253 0
>  467              	.LBB6:
>  468 03ec 0339A0E3 		mov	r3, #49152
>  469 03f0 8E3283E2 		add	r3, r3, #-536870904
>  470 03f4 0030D3E5 		ldrb	r3, [r3, #0]	@
> zero_extendqisi2
>  471 03f8 0F3003E2 		and	r3, r3, #15
> 
> ......
> ......
> 
>  296: ****           default:
>  297: ****             IOSET1 = LED8;
>  609              		.loc 1 297 0
>  610 059c 0E32A0E3 		mov	r3, #-536870912
>  611 05a0 0A3983E2 		add	r3, r3, #163840
>  612 05a4 143083E2 		add	r3, r3, #20
>  613 05a8 0225A0E3 		mov	r2, #8388608
>  614              	.L71:
>  615 05ac 002083E5 		str	r2, [r3, #0]
>  298: ****             break;
>  299: ****         }
>  300: **** 
>  301: **** 
>  302: **** }
>  616              		.loc 1 302 0
>  617              	.L50:
>  618 05b0 7F50BDE8 		ldmfd	sp!, {r0, r1, r2, r3, r4,
> r5, r6, ip, lr}
>  619 05b4 04F05EE2 		subs	pc, lr, #4
> 
> Note that if I slighty semplify the handler (ex.
> removing the for()
> loop), the compiler needs to use less registers,
> don't save the LR
> register, does not insert the sub lr,lr,#4 opcode
> and the code work!!
> Anyone experienced similar problems and has a
> solution?
> Thank you.
> 
> 
> 
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com

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.