Yahoo Groups archive

Lpc2000

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

Message

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:
> 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/>.
>
>
> ------------------------------------------------------------------------
>

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.