Monday, September 30, 2019
Make Your Code More Assertive!
Most if not all 32 bit processors have a software instruction to fire a ‘Breakpoint’, the MIPS core used by Microchip PIC32 processors is no different.
This can be used to make a “Debug Only Breakpoint” that is useful as a standard C ‘assert()’ alternative.
Assert is a method of adding check code into your program that can be used to check assumptions about the state of variables or program status to flag problems or errors.
Using assertions can dramatically reduce programming errors, especially the errors that occur when libraries are being used .
Asserts in a PC environment are pretty easy to use as there is normally console window available or disk file to log any asserted problems to.
In a small embedded system neither of these things is typically available. However, when developing and testing code a programmer / debugger is normally attached to the system and this can be used as the window into the systems operation.
What is needed is an assert macro that fires a software breakpoint and halts the program if the system is in a debugging state and ideally for the macro to generate no code if the system is built with a production state. When using MPLAB-X and XC-32, Microchips preferred development IDE and compiler, this is easy to do.
When building a Debug image, MPLAB-X via XC-32 defines a name: “__DEBUG” (Two leading underscores). This defined name can be used to build the assert macro two ways. 1) When debugging the macro is built and when not debugging the macro generates no code, as shown below.
A simple Macro that mimics the standard C assert() call for any PIC32 based project. The macro generates a check that calls the MIPS software breakpoint if the project was built with ‘__DEBUG’ defined. This name is automatically defined by MPALB-X when a debugging mage is built.
You can put code similar to the above into a C header file.Our new macro then works just like any standard C assert() macro,
- assert_dbg(exp) where exp is non-zero does nothing (a non-assertion).
- assert_dbg(exp) where exp evaluates to zero, stops the program on a software
breakpoint if debugging mode is active in MPALB-X.
I chose to name the macro: “assert_dbg()” so that the association to a standard assert would be easy to remember (it works the same way) and I added the ‘_dbg’ suffix to show that something is slightly different here as a reminder to the programmer that this is like: “A standard assert, but slightly different”.
Naturally you can use any name you like.
While reading an article by Niall Murphy on the Barr Group website , I ran across a comment by ‘ronkinoz’ that shared another clever / useful debugging macro - I will call it ‘assert_compile()’ here.
What assert_compile() does is to check things that can be checked at compile time, if the assert fails then the compiler halts on an error.
The macro works by trying to define a typedef array with a size of one char if the assert passes, if the assert fails the array will be sized as ‘-1’ which GCC will halt on as a compile error.
This can be very useful in checking the size of known instances against known system constraints for instance.
One thing that often causes problems is making a EEPROM structure, like a Cal Constant table larger than the designed allocated space. This often happens when a project is revised and revised to add new features or as a product is developed and it is discovered that the calibration routines need to change.
You can catch things like getting a table too large and possibly overwriting other EEPROM allocations. The size of fixed objects is known to the compiler at compile time.
My first use is to peg my code to a compiler version. That way in a year or so if I forget to read my notes and try to compile the code under a different version, I will get a rude warning to take a careful look before continuing.
The macro is presented here,
 McConnell, Steve, “Code Complete, A Practical Handbook of Software Construction”, 2nd edition, page 189: “Assertions”. Microsoft Press, 2004.
Article By: Steve Hageman / www.AnalogHome.com
We design custom: Analog, RF and Embedded systems for a wide variety of industrial and commercial clients. Please feel free to contact us if we can help on your next project.