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

208  THE  ART OF  DESIGNING EMBEDDED SYSTEMS


                        clude the chip select and wait state code in-line (not as a subroutine). Be
                        careful to initialize these selects at the very top of the module, to allow fu-
                        ture subroutine calls to operate, and since some debugging tools will not
                        operate reliably until these are set up.

                             Stack and Heap Issues

                             Always initialize the stack on an even address. Resist the temptation
                        to set it to a odd value like Oxffff, since on a word machine an odd stack
                        will cripple system performance.
                             Since few programmers have a reasonable way to determine maxi-
                        mum stack requirements, always assume your estimates will be incorrect.
                        For each stack in the system, make sure the initialization code fills the en-
                        tire amount of memory allocated to the stack with the value 0x55. Later,
                        when debugging, you can view the stack and detect stack overflows by
                        seeing no blocks of 0x55 in that region. Be sure, though, that the code that
                        fills the stack with 0x55 automatically detects the stack’s size, so a late
                        night stack size change will not destroy this useful tool.
                             Embedded systems are often intolerant of heap problems. Dynami-
                        cally allocating and freeing memory may, over time, fragment the heap to
                        the point  that  the program crashes due to an inability  to allocate more
                        RAM. (Desktop programs are much less susceptible to this as they typi-
                        cally run for much shorter periods of time.)
                             So, be wary of the use of the malloc() function. When using a new
                        tool chain examine the malloc function, if possible, to see if it implements
                        garbage collection to release fragmented blocks (note that this may bring
                        in another problem, as during garbage collection the system may not be re-
                        sponsive to interrupts). Never blindly assume that allocating and freeing
                        memory is cost- or problem-free.
                             If you chose to use malloc(), always check the return value and safely
                        crash (with diagnostic information) if it fails.
                             When using C, if possible (depending on resource  issues and pro-
                        cessor limitations), always include Walter Bright’s MEM package (www.
                        snippets.org/mem.txt) with the code, at least for the debugging.
                             MEM provides:

                               ISO/ANSI verification of allocationheallocation functions
                               Logging of all allocations and frees
                               Verifications of frees
                               Detection of pointer over- and under-runs.
   216   217   218   219   220   221   222   223   224   225   226