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

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.