I'm building a project for the nRF52832 using the NRF5-SDK version 14.0.0. I'm compiling using GCC 6.3.1 (arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors 6-2017-q2-update) 6.3.1 20170620 (release) [ARM/embedded-6-branch revision 249437]
).
I made some changes to the project, and started getting hard-faults. No big deal, this is a fairly common occurrence. However, when I started digging in, I found that my hardfault was coming from the NRF_BREAKPOINT_COND
line in components/libraries/util/app_error_weak.c
-- that is, that I was actually getting a bog-standard application error, but this was being escalated into a fault, which is not desirable from a debugging standpoint.
Chasing this down further, I came across the definition of NRF_BREAKPOINT
:
/**@brief Macro for setting a breakpoint.
*/
#if defined(__GNUC__)
#define NRF_BREAKPOINT __builtin_trap()
#else
#define NRF_BREAKPOINT __BKPT(0)
#endif
It turns out the __builtin_trap()
generates the instruction udf 0xff
, which causes an undefined instruction exception (and thus the hardfault), while __BKPT(0)
generates bkpt 0x0
, which behaves as desired.
I suspect this is a difference in behavior based on the gcc
version vs. what the SDK is usually built against. Alternatively, maybe different debuggers/debug servers (I'm using J-Link PLUS/JLinkGDBServer
) appropriately handle udf 0xff
as a breakpoint.
My real question is this, then: does using __builtin_trap()
provide any advantage over just __BKPT(0)
in the general case? If so, what can I do to cause this to generate a breakpoint instead of a hard fault?