|
|
View previous topic :: View next topic |
Author |
Message |
Peter Guest
|
Postponing an interrupt execution. |
Posted: Thu Sep 20, 2007 6:25 am |
|
|
Hi all.
Am wondering if there is an easy way of postponing an execution of interrupt. Let's say I have a code being executed in a loop of main subroutine:
do sth1
do sth2
do sth3
do sth4
but I want do sth2 and do sth3 couldn't be stopped by any coming interrupts, e.g. timer. On the other hand, I don't want to miss any interrupts, just delay them for a short moment, if they happen when executing do sth 2 and do sth3.
E.g.
do sth1
{block and queue int_rttc}
do sth2
do sth3
{unblock and execute int_rttc from queue}
do sth4
Is sth like this viable? Any suggestions on how to approach this?
Regards,
Peter. |
|
|
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Thu Sep 20, 2007 7:01 am |
|
|
It works per se.
When you disable an interrupt the interrupt flag still continues being set, and when you reenable that interrupt, the ISR gets (postponedly) called if the flag has been set already before (during the time it was disabled.) if you don't clear it. You can though only queue one interrupt per type. |
|
|
Peter. Guest
|
Postponing an interrupt execution. |
Posted: Thu Sep 20, 2007 7:54 am |
|
|
Erm, I know, am wondering whether this would do or not. What happens, if there's a flag signalized, rttc int is enabled again, rttc int subroutine executes (may take long) and meantime another rttc interrupt happens b/c of the previous delay? Am taking they won't queue. Will they?
Cheers,
P. |
|
|
Ttelmah Guest
|
|
Posted: Thu Sep 20, 2007 8:50 am |
|
|
No, there is no 'stack' for the interrupt flags themselves.
However you can improve the behaviour. The default behaviour, is that the interrupt is cleared automatically by the compiler, when the handler routine _exits_.
Instead, use the 'noclear' declaration, and either:
Code: |
#int_timer1 NOCLEAR
void timer(void) {
clear_interrupts(int_timer1);
// your interrupt code
//When the interrupt exits, if the flag has become set since it was
//cleared at the start of the code, the interrut will retrigger.
}
//or
#int_timer1 NOCLEAR
void timer(void) {
do {
clear_interrupts(int_timer1);
//your interrupt code
} while (TMR1IF); //Here the code will loop, if the interrupt has
//retriggered, without the overhead of saving/restoring the registers
//associated with normal interrupt operation. Caveat though,
//is that if the handler is slow, relative to the interrupt period,
//the code may never exit....
}
|
Here, the 'NOCLEAR' directive, tells the compiler, that _you_ are going to handle clearing the interrupt, and you clear it ASAP, then allow the code to re-execute, if it triggers again.
Best Wishes |
|
|
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Thu Sep 20, 2007 9:01 am |
|
|
What happens, if there's a flag signalized, rttc int is enabled again, rttc int subroutine executes
a well-behaved isr first clears the interrupt flag, making it able to receive another interrupt signal during the time it executes. Than when it returns to normal program execution it sees the flag set again and executes a second time (so they do kinda 'queue' one level deep)
an isr should not take a long time (you will be still miss interrupts if more than two arrive). so you should move all long-taking operations to the main code using your own queuing (task-scheduling, flagging) technique if you wish (your own queue can be of any depth) |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Sep 20, 2007 9:46 am |
|
|
If your interrupt is not time sensitive you could simply set a flag, in the interrupt, and then check, inside of main(), to see if the flag has been set. Call whatever routine you need to and clear the flag.
Ronald |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|