|
3
Gordon Drive, P.O.Box 1347 Rockland, Maine 04841 U.S.A.
|
|
© 2004 Avocet Systems, Inc.
|
Call
Us Today at 207-596-7766 ("Picton Press")
|
|
Avocet Systems, Inc. : The Complete Solution for Embedded Systems
Development Tools
|
|
|
Embedded Update
Debugging Embedded Software
Since most of us write error-free code, debugging is hardly an issue. We carefully
plan our design, include range checks on arguments, have associates read the
code before trying it out, and do everything possible to insure that it runs
correctly immediately.
Not.
The emulator/debugger industry thrives because of the fact the programmers make
mistakes - LOTs of mistakes. Errors are expected and tolerated.
It would be awful to be a civil engineer. Can you imagine telling your boss
that the bridge you just erected has a few bugs, "but don't worry - we'll
release version 1.1 in a few months!"
Write your code assuming it will be riddled with bugs. Do all of the good things
we know we should do.... yet that are too often ignored.
Crazy, complex, convoluted code is simply unacceptable. It's always either impossible
to debug, or too costly to debug. By assuming it will be full of bugs, then
you clearly should either document it to death or avoid the complex code altogether.
One old adage is "program for clarity first, optimize second". Nah.
Never remove clarity. You might be a genius; assume your successor will be an
idiot.
If, when reading your code, you ever see something that makes you scratch your
head and wonder how it does something: instantly rewrite or recomment it!
Constrain time-sensitive code to small routines. Spawn tasks off that can process
non-critical activities in the background. Clearly identify the timing limitations
expected in each interrupt service routine.
Use decent tools. Your time is expensive.
Never, ever, not in a thousand years, write an I/O instruction in the body of
the code. Yes, by their nature embedded systems interact constantly with the
outside world. Restrict I/O to subroutines ("get_uart_data"). When
performance is an issue, and you can't stand the overhead of the CALLs, RETURNs,
and inherent argument stacking, then put the I/O in a C macro. Someday the I/O
WILL change.
If you are using decent tools, remove them and burn a ROM once in a while. It's
a quick way to insure there's not a lurking uninitialized variable, or weird
hardware problem, that will keep the system from running standalone.
Use a reasonable debugging strategy. Don't start changing things for no reason.
Never proceed without truly understanding the problem. This is the curse of
all projects: a very smart person gets just a glimpse at a problem and immediately
jumps to a conclusion before even finding out what all of the symptoms are.
Never make assumptions. It's easy to toss out one symptom because "it's
clearly related to the other problem." Are you sure? Can you prove it?
Symptoms are all you have to go on when debugging; be reluctant to discard them
because they don't fit your model of possible causes.
Finally, use the scientific method:
|
|
|