EmbeddedRelated.com
Forums

Can't understand interrupts

Started by Cristi Neagu January 13, 2012
Hello. I'm a newb on these forums and on ARM programming, so any help would be appreciated.

I've been trying to get my head around interrupts, and i'm not making any progress. I've been looking over the LPC2119 manual, as well as over "The Insider's Guide for Philips" book, and I can't figure out what i'm doing wrong.

What I'm trying to do is to generate a fast interrupt via EXTINT1 that will turn on a LED (it's inverted, so clearing the pin will turn the LED on).

Here's some code (I use Keil, btw):

Interrupt handler:

void FIQ_Handler(void) __irq
{
IOCLR0 = 0x10000; //Set the LED pins
EXTINT = 0x00000002; //Clear the peripheral interrupt flag
}

Interrupt initialization:

void initFiq(void)
{
IODIR0 = 0x10000; //Set the LED pins as outputs
PINSEL0 |= 0xC0; //Enable the EXTINT1 interrupt
VICIntSelect = 0x00008000; //Enable a Vic Channel as FIQ
VICIntEnable = 0x00008000;
}

Main program:

int main (void)
{
init_serial0(0x30);
initFiq(); //Initialize the Fast interrupt source
IOSET0 = 0x10000;
while(1)
{
printf("Waiting for interrupt\n");
}
}

And vectors in startup.s

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, [PC, #-0x0FF0] ; Vector from VicVectAddr
LDR PC, FIQ_Addr

Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD 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 IRQ_Handler
FIQ_Handler B FIQ_Handler

Sorry for the long message.

I did a version that sends a message over UART after every instruction, and the problem is that the program hangs exactly after the interrupt is triggered, without ever entering the handler. The debbuger confirms this. I believe that the VIC doesn't know what the handler's address is, but I have absolutely no idea how to set that (I do know it has something to do with the vector list).

Thanks.

An Engineer's Guide to the LPC2100 Series

If you break into the execution it seems likely you are at the line:
FIQ_Handler B FIQ_Handler

Often when calling C from ASM there is a hidden '_'
So
FIQ_Handler B _FIQ_Handler
may be closer to what you want.
--- In l..., "Cristi Neagu" wrote:
>
> Hello. I'm a newb on these forums and on ARM programming, so any help would be appreciated.
>
> I've been trying to get my head around interrupts, and i'm not making any progress. I've been looking over the LPC2119 manual, as well as over "The Insider's Guide for Philips" book, and I can't figure out what i'm doing wrong.
>
> What I'm trying to do is to generate a fast interrupt via EXTINT1 that will turn on a LED (it's inverted, so clearing the pin will turn the LED on).
>
> Here's some code (I use Keil, btw):
>
> Interrupt handler:
>
> void FIQ_Handler(void) __irq
> {
> IOCLR0 = 0x10000; //Set the LED pins
> EXTINT = 0x00000002; //Clear the peripheral interrupt flag
> }
>
> Interrupt initialization:
>
> void initFiq(void)
> {
> IODIR0 = 0x10000; //Set the LED pins as outputs
> PINSEL0 |= 0xC0; //Enable the EXTINT1 interrupt
> VICIntSelect = 0x00008000; //Enable a Vic Channel as FIQ
> VICIntEnable = 0x00008000;
> }
>
> Main program:
>
> int main (void)
> {
> init_serial0(0x30);
> initFiq(); //Initialize the Fast interrupt source
> IOSET0 = 0x10000;
> while(1)
> {
> printf("Waiting for interrupt\n");
> }
> }
>
> And vectors in startup.s
>
> 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, [PC, #-0x0FF0] ; Vector from VicVectAddr
> LDR PC, FIQ_Addr
>
> Reset_Addr DCD Reset_Handler
> Undef_Addr DCD Undef_Handler
> SWI_Addr DCD SWI_Handler
> PAbt_Addr DCD PAbt_Handler
> DAbt_Addr DCD DAbt_Handler
> DCD 0 ; Reserved Address
> IRQ_Addr DCD IRQ_Handler
> FIQ_Addr DCD 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 IRQ_Handler
> FIQ_Handler B FIQ_Handler
>
> Sorry for the long message.
>
> I did a version that sends a message over UART after every instruction, and the problem is that the program hangs exactly after the interrupt is triggered, without ever entering the handler. The debbuger confirms this. I believe that the VIC doesn't know what the handler's address is, but I have absolutely no idea how to set that (I do know it has something to do with the vector list).
>
> Thanks.
>

--- In l..., "John S" wrote:
>
> If you break into the execution it seems likely you are at the line:
> FIQ_Handler B FIQ_Handler
>
> Often when calling C from ASM there is a hidden '_'
> So
> FIQ_Handler B _FIQ_Handler
> may be closer to what you want.
>
Thanks for the reply.

I tried your suggestion. I get "error: A1516E: Bad symbol '_FIQ_Handler', not defined or external". I also tried "__FIQ_Handler" (notice the double "__"), as used in the call to __main, lower down the startup.s, getting the same error. These are assembler errors.

So I tried using "IMPORT __FIQ_Handler". Now I get "Error: L6218E: Undefined symbol __FIQ_Handler (referred from startup.o).", which is a linker error. I also tried with single "_", with the same result.

I also tried all of the above with the line

FIQ_Addr DCD FIQ_Handler

with exactly the same result. Yes, I don't know what I'm doing exactly, so I'm covering all bases. I even tried renaming the function.

So... back to square one...

Hi:

If you are new to ARM, would you be able to start using Cortex-M3 processors instead (LPC1700 family)? The newer core has an integrated Nested Vector Interrupt controller that facilitates interrupt handling and programming (no more VIC programming!). In fact, no assembly programming either (unless you really need to get into the details)

Additionally, you can use the CMSIS libraries to handle the peripherals (http://www.onarm.com/cmsis/download/).

Regards,

Alex.

--- In l..., "Cristi Neagu" wrote:
>
> Hello. I'm a newb on these forums and on ARM programming, so any help would be appreciated.
>
> I've been trying to get my head around interrupts, and i'm not making any progress. I've been looking over the LPC2119 manual, as well as over "The Insider's Guide for Philips" book, and I can't figure out what i'm doing wrong.
>
> What I'm trying to do is to generate a fast interrupt via EXTINT1 that will turn on a LED (it's inverted, so clearing the pin will turn the LED on).
>
> Here's some code (I use Keil, btw):
>
> Interrupt handler:
>
> void FIQ_Handler(void) __irq
> {
> IOCLR0 = 0x10000; //Set the LED pins
> EXTINT = 0x00000002; //Clear the peripheral interrupt flag
> }
>
> Interrupt initialization:
>
> void initFiq(void)
> {
> IODIR0 = 0x10000; //Set the LED pins as outputs
> PINSEL0 |= 0xC0; //Enable the EXTINT1 interrupt
> VICIntSelect = 0x00008000; //Enable a Vic Channel as FIQ
> VICIntEnable = 0x00008000;
> }
>
> Main program:
>
> int main (void)
> {
> init_serial0(0x30);
> initFiq(); //Initialize the Fast interrupt source
> IOSET0 = 0x10000;
> while(1)
> {
> printf("Waiting for interrupt\n");
> }
> }
>
> And vectors in startup.s
>
> 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, [PC, #-0x0FF0] ; Vector from VicVectAddr
> LDR PC, FIQ_Addr
>
> Reset_Addr DCD Reset_Handler
> Undef_Addr DCD Undef_Handler
> SWI_Addr DCD SWI_Handler
> PAbt_Addr DCD PAbt_Handler
> DAbt_Addr DCD DAbt_Handler
> DCD 0 ; Reserved Address
> IRQ_Addr DCD IRQ_Handler
> FIQ_Addr DCD 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 IRQ_Handler
> FIQ_Handler B FIQ_Handler
>
> Sorry for the long message.
>
> I did a version that sends a message over UART after every instruction, and the problem is that the program hangs exactly after the interrupt is triggered, without ever entering the handler. The debbuger confirms this. I believe that the VIC doesn't know what the handler's address is, but I have absolutely no idea how to set that (I do know it has something to do with the vector list).
>
> Thanks.
>

Thanks for the suggestion.

I do have an STM32F103 lying around, but I wanted to learn to program this LPC2119 first, mostly because apparently it's easier to find basic examples for ARMv7 than it is for CortexM3's. I've also followed the other thread about v7 vs M3, and I agree with "there is a time and place for both of them". Also, if I do give up on the LPC2119, what will I do with it?

Having two development boards lying around is better than having just one. Tough i do agree that it is preferable to be able to program at least one of them:P

Thanks again :)

--- In l..., "alexander_ribero" wrote:
>
> Hi:
>
> If you are new to ARM, would you be able to start using Cortex-M3 processors instead (LPC1700 family)? The newer core has an integrated Nested Vector Interrupt controller that facilitates interrupt handling and programming (no more VIC programming!). In fact, no assembly programming either (unless you really need to get into the details)
>
> Additionally, you can use the CMSIS libraries to handle the peripherals (http://www.onarm.com/cmsis/download/).
>
> Regards,
>
> Alex.
>

must you use asm language? There are lots of examples in C or C++.
Hello. I'm a newb on these forums and on ARM programming, so any help would be appreciated.
>
>I've been trying to get my head around interrupts, and i'm not making any progress. I've been looking over the LPC2119 manual, as well as over "The Insider's Guide for Philips" book, and I can't figure out what i'm doing wrong.
>
>What I'm trying to do is to generate a fast interrupt via EXTINT1 that will turn on a LED (it's inverted, so clearing the pin will turn the LED on).
>
>Here's some code (I use Keil, btw):
>
>Interrupt handler:
>
>void FIQ_Handler(void) __irq
>{
> IOCLR0 = 0x10000; //Set the LED pins
> EXTINT = 0x00000002; //Clear the peripheral interrupt flag
>}
>
>Interrupt initialization:
>
>void initFiq(void)
>{
> IODIR0 = 0x10000; //Set the LED pins as outputs
> PINSEL0 |= 0xC0; //Enable the EXTINT1 interrupt
> VICIntSelect = 0x00008000; //Enable a Vic Channel as FIQ
> VICIntEnable = 0x00008000;
>}
>
>Main program:
>
>int main (void)
>{
> init_serial0(0x30);
> initFiq(); //Initialize the Fast interrupt source
> IOSET0 = 0x10000;
> while(1)
> {
> printf("Waiting for interrupt\n");
> }
>}
>
>And vectors in startup.s
>
>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, [PC, #-0x0FF0] ; Vector from VicVectAddr
> LDR PC, FIQ_Addr
>
>Reset_Addr DCD Reset_Handler
>Undef_Addr DCD Undef_Handler
>SWI_Addr DCD SWI_Handler
>PAbt_Addr DCD PAbt_Handler
>DAbt_Addr DCD DAbt_Handler
> DCD 0 ; Reserved Address
>IRQ_Addr DCD IRQ_Handler
>FIQ_Addr DCD 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 IRQ_Handler
>FIQ_Handler B FIQ_Handler
>
>Sorry for the long message.
>
>I did a version that sends a message over UART after every instruction, and the problem is that the program hangs exactly after the interrupt is triggered, without ever entering the handler. The debbuger confirms this. I believe that the VIC doesn't know what the handler's address is, but I have absolutely no idea how to set that (I do know it has something to do with the vector list).
>
>Thanks.
>
>
At the very least, you need to embed some asm code to return from the
interrupt in a C interrupt handler. That C isr function also has to be
declared "naked" so the compiler doesn't do the usual stack manipulations
or a normally called function.

For me it's just as easy to write the ISR in asm and be done with.

DaveS

On Fri, Jan 13, 2012 at 9:56 PM, wrote:

> **
> must you use asm language? There are lots of examples in C or C++.
>
> Hello. I'm a newb on these forums and on ARM programming, so any help
> would be appreciated.
> >
> >I've been trying to get my head around interrupts, and i'm not making any
> progress. I've been looking over the LPC2119 manual, as well as over "The
> Insider's Guide for Philips" book, and I can't figure out what i'm doing
> wrong.
> >
> >What I'm trying to do is to generate a fast interrupt via EXTINT1 that
> will turn on a LED (it's inverted, so clearing the pin will turn the LED
> on).
> >
> >Here's some code (I use Keil, btw):
> >
> >Interrupt handler:
> >
> >void FIQ_Handler(void) __irq
> >{
> > IOCLR0 = 0x10000; //Set the LED pins
> > EXTINT = 0x00000002; //Clear the peripheral interrupt flag
> >}
> >
> >Interrupt initialization:
> >
> >void initFiq(void)
> >{
> > IODIR0 = 0x10000; //Set the LED pins as outputs
> > PINSEL0 |= 0xC0; //Enable the EXTINT1 interrupt
> > VICIntSelect = 0x00008000; //Enable a Vic Channel as FIQ
> > VICIntEnable = 0x00008000;
> >}
> >
> >Main program:
> >
> >int main (void)
> >{
> > init_serial0(0x30);
> > initFiq(); //Initialize the Fast interrupt source
> > IOSET0 = 0x10000;
> > while(1)
> > {
> > printf("Waiting for interrupt\n");
> > }
> >}
> >
> >And vectors in startup.s
> >
> >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, [PC, #-0x0FF0] ; Vector from VicVectAddr
> > LDR PC, FIQ_Addr
> >
> >Reset_Addr DCD Reset_Handler
> >Undef_Addr DCD Undef_Handler
> >SWI_Addr DCD SWI_Handler
> >PAbt_Addr DCD PAbt_Handler
> >DAbt_Addr DCD DAbt_Handler
> > DCD 0 ; Reserved Address
> >IRQ_Addr DCD IRQ_Handler
> >FIQ_Addr DCD 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 IRQ_Handler
> >FIQ_Handler B FIQ_Handler
> >
> >Sorry for the long message.
> >
> >I did a version that sends a message over UART after every instruction,
> and the problem is that the program hangs exactly after the interrupt is
> triggered, without ever entering the handler. The debbuger confirms this. I
> believe that the VIC doesn't know what the handler's address is, but I have
> absolutely no idea how to set that (I do know it has something to do with
> the vector list).
> >
> >Thanks.
> >
> >
> >
> >
>
>


--- In l..., childresss@... wrote:
>
> must you use asm language? There are lots of examples in C or C++.
>

The only assembly code in there is the startup file, which, as far as I know, must be in assembler.

And do you mind sharing one of those examples, because I can't seem to find any in which a fast interrupt is declared.

--- In l..., David Smead wrote:
>
> At the very least, you need to embed some asm code to return from the
> interrupt in a C interrupt handler. That C isr function also has to be
> declared "naked" so the compiler doesn't do the usual stack manipulations
> or a normally called function.
>
> For me it's just as easy to write the ISR in asm and be done with.
>
> DaveS
>

Would you be willing to post an example of that?

My problem, as I see it, is that I don't know how to tell the whatever-it-is-that-has-to-know-where-the-interrupt-handler-is where the interrupt handler is.

I was trying to get software interrupts to work by following the example in Keil's help files , and I ran in the same problem. The handler function compiles OK, it is called OK, but everything hangs when it gets to the vector table. Could you please give me a small example of how the vector table in startup.s is set up?

Thanks.

On 13.01.2012 22:05, Cristi Neagu wrote:
> I also tried all of the above with the line
>
> FIQ_Addr DCD FIQ_Handler

I think that is close but you also have to write the name in the same
way as your compiler exports it (with two, one or no '_':s) _and_
declare it as external in startup.s (you get the idea from how main is
declared) _and_ make the handler interrupt function (what you have done
(__irq) may be enough - I don't know Keil).

--

Timo