Enforcing debugger breakpoints in ChibiOS chDbgAssert()

ChibiOS provides a variety of debug functions that can be enabled or disabled using preprocessor definitions.

When debugging ARM-based microcontrollers like the STM32, it can be useful to hardcode

This post provides a simple method of improving the definition of chDbgAssert() in chdebug.h so that a breakpoint is enforced in case of assertion failures. By using the ARM BKPT instruction, the overhead is only a single assembler instruction.

Note that we use GCC inline assembler syntax here. When using other compilers, you’ll need to port the syntax correspondingly.

Original ChibiOS 2.6.6 code:

example.c
#if !defined(chDbgAssert)
#define chDbgAssert(c, m, r) {                                              \
  if (!(c))                                                                 \
    chDbgPanic(m);                                                          \
}
#endif /* !defined(chDbgAssert) */

Modified code:

example.c
#if !defined(chDbgAssert)
#define chDbgAssert(c, m, r) {                                              \
  if (!(c)) {                                                               \
    __asm volatile("BKPT #0\n");                                            \
    chDbgPanic(m);                                                          \
  }                                                                         \
}
#endif /* !defined(chDbgAssert) */

Note that the inline assembler is also available as CMSIS function: __BKPT. In the default configuration, ChibiOS 2.6.6 does not allow using CMSIS in chdebug.h without additional #include statements.

Note that this code snippet & the corresponding patch is licensed under the same license as ChibiOS.

Update 2014-10-23:

It is also occasionally useful to add the BKPT statement into the implementation of chDbgPanic in chdebug.c:

example.cpp
void chDbgPanic(const char *msg) {
  __asm volatile("BKPT #0\n");
  dbg_panic_msg = msg;
  chSysHalt();
}

Update 2014-11-01:

By default, ChibiOS 2.6.6 uses chSysHalt() as handler for LWIP_PLATFORM_ASSERT. In other words, the method described above will not catch LWIP assertions by default.

In order to fix this, open os/various/lwip_bindings/arch/cc.h and replace

example.c
#define LWIP_PLATFORM_ASSERT(x) {                                       \
  chSysHalt();                                                          \
}

by

example.c
#define LWIP_PLATFORM_ASSERT(x) {                                       \
  chDbgPanic(x);                                                        \
}

which doesn’t throw away the error message but will break in the chDbgPanic() implementation listed above and hence will show you the error message directly.


Check out similar posts by category: Embedded