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

68  THE ART OF  DESIGNING EMBEDDED SYSTEMS


                          mov     ax, [j+ll
                          adc     ax, 0          ; prop  carry  to high  part  of  j
                          mov     [j+ll ,ax

                          An  interrupt in  the  middle of  this code will  leave j just partially
                      changed: if the ISR is reincarnated with j in transition, its value will surely
                      be corrupt. Or, if other routines use the variable, the ISR may change its
                      value at the same time other code tries to make sensible use of it.
                          The first solution is to avoid global variables! Globals are an abomi-
                      nation, a sure source of problems in any system, and an utter nightmare in
                      real-time code. Never, ever pass data between routines in globals unless
                      the following three conditions are fulfilled:


                             Reentrancy issues are dealt with via some method,  such as dis-
                             abling interrupts around their use-though   I do not recommend
                             disabling interrupts cavalierly, since that affects latency.
                             The globals are absolutely needed because of a clear performance
                             issue. Most alternatives do impose some penalty in execution time.
                             The global use is limited and well documented.

                          Inside of an ISR, be wary of any variable declared as a static. Though
                      statics have their uses, the ISR that reenables interrupts, and then is inter-
                      rupted before it completes, will destroy any statics declared within.
                          In 1997, on a dare, I examined firmware embedded in 23 completed
                      products, all of which were shipping to customers. Every one had this par-
                      ticular problem! Interestingly, the developers of 70% of the projects ad-
                      mitted  to infrequent,  unexplainable  crashes or other odd behavior.  One
                      frustrated engineer revealed that his product burped almost hourly, a symp-
                      tom “corrected” (perhaps “masked” would be a better term) by adding a
                      very robust watchdog timer circuit. This particularly bad system, which
                      had the reentrancy problem inside an ISR, also had the fastest interrupt rate
                      of any of the products examined.
                          This suggests using a stress test to reveal latent reentrancy defects.
                      Crank up the interrupt rates! If the timer comes once per second, try driv-
                      ing it every millisecond and see how the system responds. Assuming per-
                      formance issues don’t crash the code, this simple test often shows a horde
                      of hidden flaws.
                          Even the perfectly coded reentrant ISR leads to problems. If  such a
                      routine runs so slowly that interrupts keep giving birth to additional copies
                      of it, eventually the stack will fill. Once the stack bangs into your variables,
                      the program is on its way to oblivion. You must ensure that the average in-
   76   77   78   79   80   81   82   83   84   85   86