Is it safe to remove DEBUG_NRF and not reset in ASSERT?

Hi,

It seems like there are many instances of ASSERT/NRFX_ASSERT that execute crucial checks prior to actions like dereferencing pointers, and they perform a reset if the assert fails. If DEBUG_NRF is not defined and ASSERT gets compiled out, is there any danger of the device entering an irrecoverable fault state without these asserts to reset the device? Presumably, DEBUG_NRF is not intended to be used for production, but I'd like to confirm that this is the case. Thanks!

Parents
  • Hi,

    It is a very good question and I want to answer this so that it can help others also.

    The assert handler in app_error_fault_handler is by default defined to be _WEAK declarations. That is the SDK gives you a default implementation where you

    1. DEBUG is defined for your project and the default behavior is that the system resets with assert after the logs (if enabled) are flushed out.
    2. DEBUG is NOT defined and the default behavior is that the details of the assert are saved into the memory with the CPU looping for ever.

    Either way in this case the CPU is either reset or set to loop forever which is ok. This behavior can be changed by any application as it fits them and is also the main reason to make this definition _WEAK (expecting the application to override this if needed)

    If DEBUG_NRF is not defined and ASSERT gets compiled out, is there any danger of the device entering an irrecoverable fault state without these asserts to reset the device?

    If DEBUG_NRF is mainly intended for development to catch the library/driver usage/functional error and are expected not to be used once you have done unit and system level testing. It is norm that you do not use this in production. If you fear that you might miss the corner case testing where after production a potential ASSERT situation might occur and with asserts compiled out, then the device will soon end up hardfaulting or memfaulting. This kind of  faults are not compile time removable and  that will be handled differently in the fault exception handler which is different and is implemented in components\libraries\hardfault\hardfault_implementation.c. The default behavior here is also _WEAK implementatio which does a system reset by default and the application can override this behavior.

    In short

    NRFX_ASSERT relies on your application level testing to get triggers on fault usage of libraries/drivers, and compiling them out always has a danger that your system might go to a fault when a corner case is triggered. In that case the device most likely creates a hardware fault sooner or later and is handled again in the hardfault handler (which is not compiled away)

Reply
  • Hi,

    It is a very good question and I want to answer this so that it can help others also.

    The assert handler in app_error_fault_handler is by default defined to be _WEAK declarations. That is the SDK gives you a default implementation where you

    1. DEBUG is defined for your project and the default behavior is that the system resets with assert after the logs (if enabled) are flushed out.
    2. DEBUG is NOT defined and the default behavior is that the details of the assert are saved into the memory with the CPU looping for ever.

    Either way in this case the CPU is either reset or set to loop forever which is ok. This behavior can be changed by any application as it fits them and is also the main reason to make this definition _WEAK (expecting the application to override this if needed)

    If DEBUG_NRF is not defined and ASSERT gets compiled out, is there any danger of the device entering an irrecoverable fault state without these asserts to reset the device?

    If DEBUG_NRF is mainly intended for development to catch the library/driver usage/functional error and are expected not to be used once you have done unit and system level testing. It is norm that you do not use this in production. If you fear that you might miss the corner case testing where after production a potential ASSERT situation might occur and with asserts compiled out, then the device will soon end up hardfaulting or memfaulting. This kind of  faults are not compile time removable and  that will be handled differently in the fault exception handler which is different and is implemented in components\libraries\hardfault\hardfault_implementation.c. The default behavior here is also _WEAK implementatio which does a system reset by default and the application can override this behavior.

    In short

    NRFX_ASSERT relies on your application level testing to get triggers on fault usage of libraries/drivers, and compiling them out always has a danger that your system might go to a fault when a corner case is triggered. In that case the device most likely creates a hardware fault sooner or later and is handled again in the hardfault handler (which is not compiled away)

Children
No Data
Related