View previous topic :: View next topic |
Author |
Message |
evsource
Joined: 21 Nov 2006 Posts: 129
|
What's a nifty way to jump to certain code after interrupt |
Posted: Wed Feb 28, 2007 6:32 pm |
|
|
Over an RS-232, I'm sending commands to a 16F876A. I'm receiving the bytes using the INT_RDA interrupt.
When certain commands are sent, upon return to main, I'd like to immediately go into a subroutine. The problem with this is some of the operations happening within main when an interrupt is fired take some time to complete upon return from the interrupt. Hence, the commands received in the interrupt aren't very responsive.
Any ideas on how I could overcome this? I know the *wrong* way would be to have the desired subroutines called from within the interrupt - but I know that's incorrect.
Thanks! |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
Re: What's a nifty way to jump to certain code after interru |
Posted: Wed Feb 28, 2007 7:33 pm |
|
|
evsource wrote: | I know the *wrong* way would be to have the desired subroutines called from within the interrupt - but I know that's incorrect.
|
I would recommend a subroutine call from the interrupt. It's not always a wrong way. If the subroutine you want to call executes quickly with respect to the worst-case (shortest) delay between the interrupts, and if the timing is critical - you can call the subroutine from the ISR.
By the way, if you give us a little more context of your problem, you would get more useful responses. E.g. :
- What is the time-critical task?
- What are the timing requirements?
- What does the main() do on a background? |
|
|
evsource
Joined: 21 Nov 2006 Posts: 129
|
Re: What's a nifty way to jump to certain code after interru |
Posted: Thu Mar 01, 2007 12:31 am |
|
|
kender wrote: |
I would recommend a subroutine call from the interrupt. It's not always a wrong way. If the subroutine you want to call executes quickly with respect to the worst-case (shortest) delay between the interrupts, and if the timing is critical - you can call the subroutine from the ISR. |
The subroutine could take a while to complete. The initial INT_RDA interrupt would get fired when a user (which could be someone typing and could be software handling it) sends a single byte hexadecimal command, e.g. setting a threshold. The next byte that the PIC program is expecting is the parameter, e.g. what the threshold is. In the case of software interaction with the PIC, the commands would come very quickly. But if the user is plunking out the commands, it could take on the order of seconds.
Explaining this is getting my mind churning with ideas. The initial command byte would be processed in a subroutine called from within the INT_RDA interrupt. All the subroutine would do is recognize that it was a command, and determine how many bytes should follow it as parameters. Subsequent bytes received would be recognized as the parameters. As soon as the number of required parameter bytes were received, the appropriate subroutine to process the command would be called, which would quickly execute since the parameters were already received.
kender wrote: |
By the way, if you give us a little more context of your problem, you would get more useful responses. E.g. :
- What is the time-critical task?
- What are the timing requirements?
- What does the main() do on a background? |
main() is communicating with several (up to 16) other PICs that are collecting data. Sometimes, those other PICs take awhile to respond since they are waiting on certain events. The entire process to collect from all PICs can take 1-2 seconds. So if a user enters a command, it can be very unresponsive if main() is just beginning a new batch of requests. I think the method I described above will satisfy my requirements - commands with their parameters will be received immediately, and the polling loop will continue on its merry with only very short interrupts from the ISR. |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Thu Mar 01, 2007 1:30 am |
|
|
evsource wrote: | The subroutine could take a while to complete. |
There’s no free lunch: if (on the long run) the cumulative processing time for the interrupt is longer then the average time between the interrupts, you will be loosing the interrupts. You just need to have the processing budget meet.
I think, what you want to accomplish can be called “serial communication protocol engine”. Here’s a standard way of doing this:
- ISR receives the bytes and stores them in a global array (buffer). When the ISR determines that it has a complete command, it will set a flag (global variable).
- main() checks the flag in a loop and processes the command. To speed up the response – check the flag every time after you poll a slave (16 times in a full cycle instead of 1).
evsource wrote: | …those other PICs take awhile to respond since they are waiting on certain events |
IMHO, the fact that one of the slaves can cause the master to suspend for a long time is a design flaw. You need a way for a slave to tell a master that the slave is busy and the master would procede with its own duties and check the slave later.
Last edited by kender on Sat Mar 17, 2007 12:55 am; edited 1 time in total |
|
|
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Sat Mar 03, 2007 8:25 am |
|
|
Hi,
You could set a variable flag in the isr and then poll this variable in the main function.
For example to process the INT_RDA interrupt you could use...
Code: |
#iNT_RDA
usart_isr()
{
bRcvFlg=TRUE;
cRcvData=getc();
}
void main()
{
do
{
if (bRcvFlg==TRUE)
{
bRcvFlg=FALSE;
//<the>
}
}while(TRUE);
}
|
Hope this helps you ...
thanks
arunb |
|
|
|