Page 227 - The Art of Designing Embedded Systems
P. 227

214  THE  ART  OF  DESIGNING EMBEDDED SYSTEMS


                             Functions

                             Regardless of language, keep functions small!  The ideal size is less
                        than a page; in no case should a function ever exceed two pages. Break
                        large functions into several smaller ones.
                             The only exception to this rule is the very rare case where real time
                        constraints (or sometimes stack limitations) mandate long sequences of in-
                        line code. The project manager must approve all such code. . . but first
                        look hard for a more structured alternative!
                             Explicitly declare every parameter passed to each function. Clearly
                        document the meaning of the parameter in the comments.
                             Define a prototype for every called function, with the exception of
                        those in the compiler’s runtime library. Prototypes let the compiler catch
                        the all-too-common errors of incorrect argument types and improper num-
                        bers of arguments. They are cheap insurance.
                             In general, function names should follow the variable naming proto-
                        col. Remember that functions are the “verbs” in programs-they  do things.
                        Incorporate the concept of “action words” into the variables’ names. For
                        example, use “read-A/D”  instead of “A/D-data,”  or “send-to-LCD’  in-
                        stead of “LCD-out.”



                             Interrupt Sewice Routines
                             ISRs, though usually a small percentage of the code, are often the
                        hardest bits of firmware to design and debug. Crummy ISRs will destroy
                        the project schedule!
                             Decent  interrupt routines, though, require properly designed hard-
                        ware. Sometimes it’s tempting to save a few gates by letting the external
                        device just toggle the interrupt line for a few microseconds. This is unac-
                        ceptable. Every interrupt must be latched until acknowledged, either by
                        the processor’s interrupt-acknowledge cycle (be sure the hardware acks
                        the proper interrupt source), or via a handshake between the code and the
                        hardware.
                             Use the non-maskable interrupt only for catastrophic events, like the
                        apocalypse or imminent power failure. Many tools cannot properly debug
                        NMI code. Worse, NMI is guaranteed to break non-reentrant code.
                             If at all possible, design a few spare I/O bits in the system. These are
                        tremendously useful for measuring ISR performance.
                             Keep ISRs short! Long (too many lines of  code) and slow are the
                        twins of ISR disaster. Remember that long and slow may be disjoint; a five-
                        line ISR with a loop can be as much of a problem as a loop-free 500-line
   222   223   224   225   226   227   228   229   230   231   232