??? 10/07/06 19:06 Modified: 10/07/06 19:29 Read: times Msg Score: +2 +1 Good Answer/Helpful +1 Informative |
#125970 - Abstraction: NOT Always Bad Responding to: ???'s previous message |
Erik said:
when are people going to learn that 'abstraction', which may be OK for large powerful computers such as the PC has no place in small embedded? Oh, my. This statement is a little bit too black-and-white to let it go unchallenged. First of all, we need to get over the habit of pigeon-holing various systems into categories like "small embedded", "large embedded", "large and powerful like the PC", etc., and then making simplistic, yes-or-no statements about what works in this category and what doesn't work in some other one. As Andy Neil pointed out in a recent thread, there really aren't any clear categories. Instead, we're really dealing with a continuous spectrum of systems that range from the very smallest to the very largest. Further, even if we could agree on some categories, it's still just not that easy. Some "small embedded" systems spend 99.9% of their time in an idle loop. If yours is like that, then you have permission to burn some machine cycles to make your life as a programmer easier. Feel free. It won't matter to anybody. On the other hand, some PC apps are CPU-bound, even on the hottest machines. If yours is like that, you'd best be trying to find where your code is spending its time and optimizing the hell out of the hot spots. Note also that product volume by itself doesn't automatically decide these tradeoffs. That CPU-bound PC app where every machine cycle counts might be a high end CAD program that sells 100 in a year, while the tiny micro that spends most of its life waiting for input might be buried in some toy that sells by the tens of thousands. More to the point here, however, is that "abstraction" sometimes comes without any overhead at all, and so it can and should be applied in even the smallest, most cost-sensitive systems. As an example, suppose you are programming, in C, an 8051 that controls a conveyor belt that delivers tuna cans to a machine that puts the cans into boxes. One of your inputs is a signal from the controller on the boxing machine that tells you whether it is running or not. Whenever the boxing machine stops running, you must shut down the conveyor so that the conveyor belt does not bury the boxing machine with tuna cans. The signal from the boxing machine is connected to P1.2 on your 8051. It is high (logical 1) when the boxing machine is running, and low (logical 0) when the boxing machine shuts down. For whatever reason, your program needs to check the signal in four different spots. So you write something like the following in those four different places: if (P1.2 == 0) { /* The boxer has stopped */ StopTheConveyor(); }There are deep levels of abstraction involved even in something as simple as this. The entire 'if' statement is an abstraction for the assembly code that the compiler will eventually generate. That assembly code is an abstraction for a sequence of bits that will wind up in code memory. If it's flash, each of those bits is an abstraction for the electrical charge on a floating gate within the memory somewhere. "StopTheConveyor()" is an abstraction for a process described elsewhere. "P1.2" is an abstraction for a physical pin on the device. "0" is an abstraction for a specified range of voltage levels on that pin. "Voltage" is an abstraction for physical phenomena at the atomic and subatomic levels. Etc., etc., etc. Without abstractions like these, we'd be forever stuck at square one and unable to do much more sophisticated than smashing the skulls of wooly mammoths with large stones. Every word in every language is an abstraction of some underlying concept. The statement that "abstraction ... has no place in small embedded [systems]" is just crazy, especially coming from someone who routinely promotes the value of properly named variables. Every variable name is an abstraction! Is that what they call a digression? Anyway, to continue with the example above, it can be vastly improved--at absolutely zero cost in terms of either code space or efficiency--by further abstracting the tested condition. That's right, we need more abstraction, not less. Consider this: #define TheBoxerHasStopped() (P1.2 == 0)and this: if (TheBoxerHasStopped()) { StopTheConveyor(); }Now,
-- Russ |