|
Re: Interrupts vs. Polling
Excellent question. A good way to introduce someone new to the interrupt vs. polling concept is to offer an analogy. Bear with me; it’s a bit long. Suppose you were at home one Saturday morning all alone. You had plans to go somewhere with your friends later that day so you wanted to spend the morning getting some of your homework done. Before your parents left they gave you some household chores that they wanted you to do before you were allowed to leave with your friends. Specifically, they wanted you to do several loads of laundry, put the dishes from breakfast in the dishwasher, run the dishwasher and put the dishes away after they’re clean. They were also expecting a package requiring a delivery signature to be delivered that morning and they needed you to sign for it when it arrived.
What would your morning look like if you used interrupts? You might begin by putting the dishes in the dishwasher, add some detergent and turn it on. The dishwasher doesn’t have a buzzer to indicate when the clean/dry cycle is complete so, knowing it takes 2 hours for a cycle you set the timer on the stove for 120 minutes. Then you might put the first load of laundry in the washing machine and finally settle into some homework. When you hear the washing machine’s buzzer you’d take a break from your home work, put the washed clothes in the dryer, and a new load in the washer then turn them both on and return to your homework. When the timer alerts you that the dishes are clean you get up again and put away the dishes. Finally, when you hear the doorbell, you again get up from doing your homework a third time, sign for the package and quickly return to your homework.
Now, suppose that that for some reason you were incapable of hearing any buzzers, bells, or knocks on the door. Your might plan your morning something like this: The delivery person can be reasonably be expected to wait a maximum of about 30 seconds. Therefore, I’ll need to go to the door every 30 seconds to see whether a delivery person is standing there. If I do this any less often it is possible that I’ll miss the delivery and that’s not acceptable.
Loading the dishwasher takes more than 30 seconds, so I will have to sub-divide the chore into smaller sub-chores each taking no longer than 30 seconds. I will check the door between sub-chores. After 240 delivery checks I’ll put the away the clean dishes, dividing this into less than 30-second sub-chores and continue checking the door for deliveries. In the mean time I’ll get started on the laundry.
As with the dish washing chore, from the time I collect clothes from hampers until I turn on the washing machine I will have to check the door, so I need to break this chore up into sub-chores that are less than 30 seconds each and check the door between sub-chores. A load of laundry takes about 40 minutes so after 80 delivery checks I’ll put the clothes in the dryer and more clothes in the washer, dividing this into less than 30-second sub-chores and continue checking the door for deliveries. In the mean time I’ll do my homework in 30 second segments and continue checking the door every 30 seconds.
Should the 240th delivery check after starting the dishwasher coincide with some later chore of washing more clothes, I’ll delay the start of washing more clothes until I’m done putting the dishes away, since the damp clothes from the previous load can sit for a little while in the washer and the new laundry load can wait a little while to be washed. However, under no circumstances will I delay checking the door for a deliver since that might result in my missing the delivery.
Oh yeah, if the package delivery arrives before the dishes and laundry are completed, then I can re-calculate the timing of my sub-chores and of the time blocks I allot myself for studying.
Sounds kind of crazy, doesn’t it? Yet this is somewhat analogous to the software for the driver-controlled competition segments of many teams.
Although a software design base on interrupts is conceptually easier to think about and describe, it does require a bit deeper programming skill. The level of necessary additional skill may vary among the FRC programming choices: LabVIEW, C++ and Java. However, the basic point is this: when an interrupt occurs, whatever the computer had been doing is suspended and the “interrupt service routine”, or ISR, executes instead. The code that had been interrupted by the ISR resumes when the ISR function has finished. The ISR is just a function that you have somehow registered with the operating system (details will vary) to execute upon some condition being met, such as a switch being closed (or opened). Here, there are several things to consider.
First, in general, switches don’t open and close cleanly. They bounce a lot between the open and closed states before settling down to one or the other. The bouncing happens real fast and you usually don’t notice it but with interrupts it can register as many switch closures. I won’t go into the details here as the details can vary (edge vs. level triggering; some switches might have “debounce” circuitry built in (most don’t)) but if you’re programming at a low level, you’ll need to consider whether you need a debounce strategy.
Second, the longer the ISR takes to do its thing, the longer you have suspended whatever the robot had been doing. Suppose the main code (by main code, I simply mean whatever code had been running that was interrupted by the ISR) had just turned on the drive motors at full power and was supposed to wait for 1 second and then turn the motors off. Also suppose that an interrupt occurred during that one second wait and that your ISR takes 5 seconds to finish (just for illustration purposes; 5 seconds is an exceedingly long time for an ISR). You now have an out-of-control robot for 5 seconds. In general, make your ISRs short and fast (very few milliseconds), and design them to execute in a reasonably predictable amount of time.
Third, remember that the main code can’t predict when your ISR will run. It could be between any two lines of code in the main code. In fact, it could be within any single line of code. If your ISR starts monkeying carelessly with variables used by your main code, you could introduce errors into your main code while it is running, or it could even fail altogether. Making your code safe from corruption by an ISR might be easy or difficult depending upon the situation and the code, but it takes a little experience to get the hang of it.
|