If you need assistance, please send an email to forum at 4hv dot org. To ensure your email is not marked as spam, please include the phrase "4hv help" in the subject line. You can also find assistance via IRC, at irc.shadowworld.net, room #hvcomm.
Support 4hv.org!
Donate:
4hv.org is hosted on a dedicated server. Unfortunately, this server costs and we rely on the help of site members to keep 4hv.org running. Please consider donating. We will place your name on the thanks list and you'll be helping to keep 4hv.org alive and free for everyone. Members whose names appear in red bold have donated recently. Green bold denotes those who have recently donated to keep the server carbon neutral.
Special Thanks To:
Aaron Holmes
Aaron Wheeler
Adam Horden
Alan Scrimgeour
Andre
Andrew Haynes
Anonymous000
asabase
Austin Weil
barney
Barry
Bert Hickman
Bill Kukowski
Blitzorn
Brandon Paradelas
Bruce Bowling
BubeeMike
Byong Park
Cesiumsponge
Chris F.
Chris Hooper
Corey Worthington
Derek Woodroffe
Dalus
Dan Strother
Daniel Davis
Daniel Uhrenholt
datasheetarchive
Dave Billington
Dave Marshall
David F.
Dennis Rogers
drelectrix
Dr. John Gudenas
Dr. Spark
E.TexasTesla
eastvoltresearch
Eirik Taylor
Erik Dyakov
Erlend^SE
Finn Hammer
Firebug24k
GalliumMan
Gary Peterson
George Slade
GhostNull
Gordon Mcknight
Graham Armitage
Grant
GreySoul
Henry H
IamSmooth
In memory of Leo Powning
Jacob Cash
James Howells
James Pawson
Jeff Greenfield
Jeff Thomas
Jesse Frost
Jim Mitchell
jlr134
Joe Mastroianni
John Forcina
John Oberg
John Willcutt
Jon Newcomb
klugesmith
Leslie Wright
Lutz Hoffman
Mads Barnkob
Martin King
Mats Karlsson
Matt Gibson
Matthew Guidry
mbd
Michael D'Angelo
Mikkel
mileswaldron
mister_rf
Neil Foster
Nick de Smith
Nick Soroka
nicklenorp
Nik
Norman Stanley
Patrick Coleman
Paul Brodie
Paul Jordan
Paul Montgomery
Ped
Peter Krogen
Peter Terren
PhilGood
Richard Feldman
Robert Bush
Royce Bailey
Scott Fusare
Scott Newman
smiffy
Stella
Steven Busic
Steve Conner
Steve Jones
Steve Ward
Sulaiman
Thomas Coyle
Thomas A. Wallace
Thomas W
Timo
Torch
Ulf Jonsson
vasil
Vaxian
vladi mazzilli
wastehl
Weston
William Kim
William N.
William Stehl
Wesley Venis
The aforementioned have contributed financially to the continuing triumph of 4hv.org. They are deserving of my most heartfelt thanks.
Registered Member #207
Joined: Sat Feb 18 2006, 05:14PM
Location:
Posts: 45
Hey everyone,
Alright, for starters, this question is in regard to interrupts on small, embedded processors. For example, a PIC16/18 series.
I understand the advantages of using interrupts as opposed to polling inputs. But I've always been unclear about writing effective ISRs (interrupt service routines). Everyone says that ISRs should be as short as possible, requiring as little time as possible to execute. Essentially, you should set a flag of some kind (respective to the peripheral that caused the interrupt) and exit the ISR. Now, this is what people have recommended, and seems to be the "rule of thumb."
I understand this may be an appropriate response to some interrupts, and changing one value could be a suitable routine.
However, I've commonly used interrupts for acquiring non-period input data . (For example, some device, at some point in time, will want to send data to the MCU. This data will consist of a synchronous packet of 16-bits). The interrupt will respond to the first, falling clock edge and make the MCU start reading in the data. Depending how much data is being read in, this could take a reasonably long period of time especially when compared to setting a single bit.
Is using an interrupt as described above (to indicate 'dataready') an appropriate usage of an interrupt? If inappropriate, what's an alternative?
Why does it seem that everyone recommends ISRs be as short as possible?
Registered Member #162
Joined: Mon Feb 13 2006, 10:25AM
Location: United Kingdom
Posts: 3140
ISR is most commonly used as you are using it! (or at least it was in my days) If an external event has to be serviced, then there is no alternative other than to fully serve the interruption. (e.g. my first professional project (1975/6) was an automotive distributorless ignition system, using a micro COMPLETELY interrupt driven, i.e. (other than an idle loop) no code would execute without an interrupt)
Only you the designer know the relevant importance of isr 'speed', there is no operating system or memory refresh period for a PIC etc. so the exact time response for all programme sequences can be calculated from the instruction times, if this suits your application then you're done!
Since an isr is by definition a routine to service an interrupt request, and typically MANY isr's per second occur, it makes good sense to make the isr as EFFICIENT (quick) as possible to allow the slowest/cheapest PIC etc. that will do the job. Whether the interrupt is serviced by simply setting a flag (which will in effect have to be 'polled' by the main programme) or by a very complex routine will largely be determined by the required response to an interrupt.
Specifically, to capture a serial data-stream a uart or similar function is best, most microcontroller families have onboard uart blocks, commonly requiring one irq per character, but if the other requirements of the system are minimal then a single-bit input using up to two irq per bit can easily be assembled into characters by a small routine.
I suspect that 'academics' will have lovely structured programmes, heavily commented and documented, and most of us here will have 'spahetti' code with such poor documentation that after a couple of months there's no way you can understand your own programme! (Or is that just me? ;) But with few exceptions I'd bet the 'spaghetti' code runs faster! ;)
Other members with more up-to-date experience may have different opinions !
Registered Member #30
Joined: Fri Feb 03 2006, 10:52AM
Location: Glasgow, Scotland
Posts: 6706
Short answer: Google "concurrency" and prepare to have your hair turn white overnight.
Long answer: I've designed a bunch of commercial products based on PICs and usually done it the same way as Sulaiman described: Stick the code right in the ISR.
However, tasks in your ISR must always be bounded, that is you mustn't put anything in an ISR unless you know for sure that it's going to complete before the next interrupt comes. (Unless you implement interrupt nesting, but let's not even go there.) For longer tasks that would hold up the processor too much in the ISR, you can do any of the following:
* Break them up into subtasks that are executed in order by a state machine. * Break them into a front end and a back end: the front end is in the ISR and the back end is in the main loop, typically spinning on a "Data Ready" flag or whatever.
This is how I'd attack the OP's problem: for instance I once did a PIC product that accepted human-readable commands over RS-232. The ISR just collected characters into a string buffer one at a time, and when it received a newline character, its state machine set a Data Ready flag that caused the parser in the main loop to process the buffer contents.
The crucial point is collecting characters one at a time: if the instrument were used in interactive mode from a terminal, the length of time taken to enter a whole command is unbounded, because the user could go for a coffee break, drop dead, or anything. But the time to retrieve one character from the UART is bounded. When the UART interrupt comes, you know there's a character there waiting for you.
It was double buffered, so while a command was being processed, the ISR could be collecting the next command. This basic firmware hung around for years and eventually got kludged up to 115200 baud, processing hundreds of commands per second.
All of this stuff is outdated now, in our labs we teach students to use semaphores, queues, mutexes, interrupt nesting and so on. However these techniques are arguably too heavyweight for PICs. Indeed some people have told me that the 16-series PIC instruction set can't support atomic operations at all.
This would certainly explain the grief I've had with concurrent programming on PICs over the years. For instance, I once designed an instrument with two PICs that communicated over SPI, and I could never stop the multiplexed panel lights from flickering when data came in over the SPI. In the end we just had to ship it and hope that nobody noticed.
Registered Member #207
Joined: Sat Feb 18 2006, 05:14PM
Location:
Posts: 45
Thanks a bunch for your replies. This really clears the issue up. Also, your answers reinforced my intuition in regard to writing realistic but still "useful" ISRs.
I will continue on writing my "as long as necessary" ISRs so long as they don't prevent other interrupts from occurring!
Unless somebody else has an opinion to ad, I'm good to go.
This site is powered by e107, which is released under the GNU GPL License. All work on this site, except where otherwise noted, is licensed under a Creative Commons Attribution-ShareAlike 2.5 License. By submitting any information to this site, you agree that anything submitted will be so licensed. Please read our Disclaimer and Policies page for information on your rights and responsibilities regarding this site.