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:

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

Modified code:

#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:

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

#define LWIP_PLATFORM_ASSERT(x) {                                       \
  chSysHalt();                                                          \
}

by

#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.