An assert replacement for embedded programming
30 Nov 2020 - John Z. Li
When doing C programming on MCUs,
it sometimes become impossible to use assert
because the C compiler does not implement it.
To circumvent this, and partially regain some convenience provided by assert
, we can go with the following macro definition:
#if defined(NDEBUG)
#define CHECK(fun_name, error_no, ...) ((void)0)
#else
#define CHECK(fun_name, error_no, ...) \
do { \
if (fun_name(__VA_ARGS__)) \
return error_no; \
} while (0);
#endif
This piece of code introduces a variadic macro called CHECK,
which takes a function name as its first parameter,
an error_no
to return as its second parameter,
and some unspecified number of parameters with which the function will be called.
The macro is switched on or off with the same macro definition NDEBUG
that also enable or disable asserts.
Usage of the macro is straightforward.
For example, while setting resolution of a LCD device, one defines the following checking function
static int check_resolution(int i, int j) {
if (i <= 0 || j <= 0)
return 1;
return 0;
}
which checks whether both integer i
and j
are positive,
returns 0 on success and 1 otherwise.
Then in the function set_resolution
, one can invoke runtime check as
int set_resolution(int i, int j) {
// check the precondition of the function
CHECK(check_resolution, 1, i, j);
// setting resolution
return 0;
}
So, if check fails inside the function, the function will early return with value 1. This kind of check can be applied during the debug phase to help quickly spot mistakes made by the programmer and removed in the release version, so it does not introduce extra performance loss