Pumpkin, Inc.

Pumpkin User Forums

External Interrupts

If you can't make Salvo do what you want it to do, post it here.

External Interrupts

Postby kiddster » Sun Oct 07, 2001 6:01 am

I am programming on the PIC17C756A series and using an ICE for my development. When I tried to set up port RA0 as an interrupt pin, I experienced a stack overflow.

the setup was:

ExternalIntTask ( void )
{

INTEDG = 1; /* set rising edge trigger */
INTE = 1; /* enable RA0 int */

for ( ;; )
{
OS_Delay(10, IntTask1);
if ( INTF == 1)
do something
}
}

I assume that you can use external interrupts with salvo so I must have something configured incorrectly. PEIE is set to 1 elsewhere and PORTA should come up as inputs.

Any suggestions?

kiddster
 
Posts: 5
Joined: Fri Sep 21, 2001 11:00 pm

Re: External Interrupts

Postby aek » Sun Oct 07, 2001 8:18 am

Apart from a problem with v2.2.0 that's covered in Service Bulletin SB-8, there are no known problems with interrupts on the PICs.

Stack overflow can be due to a wealth of problems that aren't related to Salvo. In your case, it appears that your ISR is incorrectly written.

I don't understand your task, though -- why would you periodically check to see if an INT pin had been set? Interrupt activity should never be polled ... I wouldn't be surprised if INTF is set regardless of the state of INTE. (On most PICs, the flag-generating mechinism is active whether or not the peripheral has its own interrupt-enable bit set). My point is that you can poll for change-on-RA0/INT activity without enabling RA0/INT interrupts.

Also, you won't be able to get an interrupt working when you clear the flag outside the ISR, which is what you're doing in ExternalIntTask(). What you want instead is something like this (this is the interrupt-based approach):

code:
void interrupt RA0ISR(void) @ 0x08
{
INTF = 0; // clear interrupt or else bad things happen
blah; // do something
}


ExternalIntTask ( void )
{

INTEDG = 1; /* set rising edge trigger */
INTE = 1; /* enable RA0 int */

for (;;) {
OS_Delay(10, IntTask1);
ugh; // detect the "do something" in RA0ISR()
}
}


With this code, you handle the interrupt when it happens via RA0ISR(), and then you act on it in a task.

Better yet, you should signal a binsem from within the ISR, and wait on that binsem in a task. This way, information "flows" from the ISR to the task, and it does so in an event-driven manner. To call OSSignalBinSem() from within an ISR, you'll need to use the OSCALL_OSXYZ config options, and also heed the advice of SB-8. Before you do that, I would suggest you simply set a flag in the ISR, and then poll it in the task, like this:

code:
void interrupt RA0ISR(void) @ 0x08
{
INTF = 0; // clear interrupt or else bad things happen
flag=1; // do something
}


ExternalIntTask ( void )
{

INTEDG = 1; /* set rising edge trigger */
INTE = 1; /* enable RA0 int */

for (;;) {
OS_Delay(10, IntTask1);
if ( flag ) {
di(); // must disable ints when clearing binsem
flag=0;
ei(); // re-enable ints
... // do stuff
}
}
}


This is "beginner's code" because polling is still involved (and various other reasons why it's not too good), but you avoid jumping into the whole "call services from an ISR" thing. Once this is working, then switch to the event-driven approach via calling OSSignalBinSem() from the ISR, and your code will get smaller, faster and more reliable.

See App Note AN-8 for some examples of calling services from within an ISR, and how to structure the task(s) accordingly.

When using interrupts, the very first thing to do is ensure that the interrupt is handled properly by the ISR. On PICs, this means that the interrupt flag must be cleared. Then, figure out how you will pass information from the ISR to the background code (e.g. task). Normally, this is done in the background by disabling interrupts, reading the "shared" information, clearing / decrementing it in the case of a binsem / sem, re-enabling interrupts, and moving on. Salvo's event-driven services handle all that for you ...

------------------

[This message has been edited by aek (edited October 07, 2001).]

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm


Return to Coding

Who is online

Users browsing this forum: No registered users and 1 guest

cron