EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

interrupt handling GCC using LPC2138

Started by ravindra_lpc July 6, 2006
hi all ,

I m using LPC2138 with GCC .I hav tested timer interrupt & External
Interrupt working .Previouosly I was using Keil ARM Tool for same
borad. I had changed startup.s file for interrupts to work.
In startup.s I changed as follows:
*********************************************************************
Vectors: LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP /* Reserved Vector */
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr

Reset_Addr: .word Reset_Handler
Undef_Addr: .word Undef_Handler
SWI_Addr: .word SWI_Handler
PAbt_Addr: .word PAbt_Handler
DAbt_Addr: .word DAbt_Handler
.word 0 /* Reserved Address */
IRQ_Addr: .word tc0
FIQ_Addr: .word FIQ_Handler

Undef_Handler: B Undef_Handler
SWI_Handler: B SWI_Handler
PAbt_Handler: B PAbt_Handler
DAbt_Handler: B DAbt_Handler
IRQ_Handler: B tc0
FIQ_Handler: B FIQ_Handler
*********************************************************************
I also declared :
void tc0(void) __attribute__ ((interrupt ("IRQ")));

In this I changed IRQ_Handler with tc0 that is the interrupt service
routine for Timer0.So plz tell me whether I m right or wrong .

Now wht should I do for other interrupt service routines .should I
change startup.s again?
What will be the case if two or more interrupts occur simultaneously?
Again
When I used separate interrupt for ADC0 by declaring
void ADC0(void) __attribute__ ((interrupt ("IRQ")));

and implemented my tested code for Keil ARM Tools and used sprintf()
function it is showing error:

/cygdrive/e/ravindra/LPC2138programs/LPC2138_GCC/adc.c(25): error:
undefined reference to `sprintf'

Can anybody plz help me tht where I m wrong.

Thanks

An Engineer's Guide to the LPC2100 Series

> I m using LPC2138 with GCC
> ...
> I also declared :
> void tc0(void) __attribute__ ((interrupt ("IRQ")));
>
> In this I changed IRQ_Handler with tc0 that is the interrupt service
> routine for Timer0.So plz tell me whether I m right or wrong .
>
> Now wht should I do for other interrupt service routines .should I
> change startup.s again?
> What will be the case if two or more interrupts occur simultaneously?

You need to use the VIC :)

Check out the examples in

http://www.ovro.caltech.edu/~dwh/ucos/project_AR1803.pdf

with code at
http://www.ovro.caltech.edu/~dwh/ucos/

Dave

--- In l..., David Hawkins wrote:
>
> > I m using LPC2138 with GCC
> > ...
> > I also declared :
> > void tc0(void) __attribute__ ((interrupt ("IRQ")));
> >
> > In this I changed IRQ_Handler with tc0 that is the interrupt
service
> > routine for Timer0.So plz tell me whether I m right or wrong .
> >
> > Now wht should I do for other interrupt service routines .should
I
> > change startup.s again?
> > What will be the case if two or more interrupts occur
simultaneously?
>
> You need to use the VIC :)
>
> Check out the examples in
>
> http://www.ovro.caltech.edu/~dwh/ucos/project_AR1803.pdf
>
> with code at
> http://www.ovro.caltech.edu/~dwh/ucos/
>
> Dave
>
thanks Dave,

will u plz tell me why printf() & sprinf() are not working in GCC.
Wht should I do to make it work?

as it is showing :
/cygdrive/e/ravindra/LPC2138programs/LPC2138_GCC/adc.c(25): error:
undefined reference to `sprintf'

bye.

> will u plz tell me why printf() & sprinf() are not working in GCC.
> Wht should I do to make it work?
>
> as it is showing :
> /cygdrive/e/ravindra/LPC2138programs/LPC2138_GCC/adc.c(25): error:
> undefined reference to `sprintf'

If you want to use standard C library functions, then you
need to link against a standard C library. The Keil tool
probably did it for you 'behind the scenes'.

Take a look in the group for building and using newlib,
and have a look at

http://www.aeolusdevelopment.com/

http://www.aeolusdevelopment.com/Articles/download.html
Dave
--- In l..., David Hawkins wrote:
> If you want to use standard C library functions, then you
> need to link against a standard C library. The Keil tool
> probably did it for you 'behind the scenes'.
>

An alternative (which we use) is to write or obtain implementations of
any standard library functions you need. If you only use a handful
(very likely in an embedded system), you can save a lot of space (code
and RAM) using this approach.

It has a secondary advantage that all code is under your own control
and you can easily move to different compilers and platforms, some of
which won't necessarily have standard libraries available.

Brendan

--- In l..., "brendanmurphy37"
wrote:
>
> --- In l..., David Hawkins wrote:
> > If you want to use standard C library functions, then you
> > need to link against a standard C library. The Keil tool
> > probably did it for you 'behind the scenes'.
> > An alternative (which we use) is to write or obtain
implementations of
> any standard library functions you need. If you only use a handful
> (very likely in an embedded system), you can save a lot of space
(code
> and RAM) using this approach.
>
> It has a secondary advantage that all code is under your own
control
> and you can easily move to different compilers and platforms, some
of
> which won't necessarily have standard libraries available.
>
> Brendan
>
Now frnd the error related to sprinf() has been removed .
Actually "Do not use standard system libraries " function was
enabled wrongly in my project settings.

Bur still the value is coming wrong .it is showing some character.
Even for the function :
printUART0("\nAIN0 Result = ");
sprintf(str,"%x%x%x",0x11,0x22,0x33);
the output on UART is coming "AIN0 Result = $?"(in string mode of
UART)
And for HEX mode of UART output is
"0D 0A 41 49 4E 30 20 52 65 73 75 6C 74 20 3D 20 BA 3F"

It seems tht sprintf() function has some problem.

plz help me to resolve it.
thanks

--- In l..., "ravindra_lpc"
wrote:
> Now frnd the error related to sprinf() has been removed .
> Actually "Do not use standard system libraries " function was
> enabled wrongly in my project settings.
>
> Bur still the value is coming wrong .it is showing some character.
> Even for the function :
> printUART0("\nAIN0 Result = ");
> sprintf(str,"%x%x%x",0x11,0x22,0x33);
> the output on UART is coming "AIN0 Result = $?"(in string mode of
> UART)
> And for HEX mode of UART output is
> "0D 0A 41 49 4E 30 20 52 65 73 75 6C 74 20 3D 20 BA 3F"
>
> It seems tht sprintf() function has some problem.
>
> plz help me to resolve it.
> thanks
>

I'm not familiar with the exact environment you're using, but two
things spring to mind imediately:

1. I wouldn't call something like "sprintf" from an interrupt
handler, for two reasons: firstly, there's a fair chance the function
is not re-entrant and secondly you could end up doing a lot of
processing in the interrupt handler, just to format stuff.

2. I particularly wouldn't call a UART driver from another interrupt
handler unless I knew for definite that the driver is written to cope
with this (i.e. both drivers and every library function they call are
fully re-entrant).

A much better approach, if you want to display conversion results is
something like:

#define BUFF_SIZE 16 // must be power-of-two
#define BUFF_SIZE_MASK (BUFF_SIZE - 1)

int buffer[BUFF_SIZE];
volatile int read_pos, write_pos;

void adc_interrupt(void)

{
buffer[write_pos] = REG(ADC_CONVERSION_RESULT);
REG(ADC_CONTROL_REG) = ??;

write_pos++;
write_pos &= BUF_SIZE_MASK;
}

// in background (i.e. not in interrupt)

void display_adc_results(void)

{
while (1)
{
if (write_pos != read_pos)
{
printf("ADC result is %d\r\n", buffer[read_pos]);
read_pos++;
read_pos &= BUF_SIZE_MASK;
}
}
}

This code has the advantage of only calling drivers from non-
interrupt code. The buffer mechanism used also avoids potential
conflicts between the reader and writer without having to disable
interrupts. There's plenty pf other potential solutions to this
however.

By the way, if you don't understand the term "re-entrant" I suggest
you look at a good book on real-time, embedded or system programming.

Brendan.


The 2024 Embedded Online Conference