This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

APP_EEROR_xx problem

Hi,

I'm using SDK17.2 to develop nRF52810's application.

When APP_ERROR_CHECK or APP_ERROR_HANDLER have a fault which is caused by hardware or software, the system will stop on the error, eventhough I have enabled watchdog.

So I need to restart my system when happened a error, what could I do?There are assembly language codes in app_error_handler.

Parents
  • Hi Taylor, 

    By default when there is an asser the chip will automatically reset (check the app_error_fault_handler() function) 

    If you define DEBUG in the project's preprocessor symbols, the app_error_handler() will be called and it will stay in an infinite loop. But I don't think WDT will be ignored. When the WDT timer is running it will continue to run and will trigger a reset if the WDT is not feed by the timer. So we need to see how you feed the WDT ? If you do that in a timer interrupt then it will continue to run and feed the WDT. 
    It's better to feed the WDT from main context or from an interrupt that at least equal or lower than other interrupts in your application. 

Reply
  • Hi Taylor, 

    By default when there is an asser the chip will automatically reset (check the app_error_fault_handler() function) 

    If you define DEBUG in the project's preprocessor symbols, the app_error_handler() will be called and it will stay in an infinite loop. But I don't think WDT will be ignored. When the WDT timer is running it will continue to run and will trigger a reset if the WDT is not feed by the timer. So we need to see how you feed the WDT ? If you do that in a timer interrupt then it will continue to run and feed the WDT. 
    It's better to feed the WDT from main context or from an interrupt that at least equal or lower than other interrupts in your application. 

Children
  • Hi Hung,

    Thanks for your reply!

    I have defined DEBUG in the project's preprocessor symbols, but WDT seems doesn't work when occured an error.

    Here is my WDT code, I have defined a 2s timer to feed.

    #include "usr_wdt.h"
    #include "nrf_drv_wdt.h"
    #include "app_timer.h"
    
    nrf_drv_wdt_channel_id m_channel_id;
    
    APP_TIMER_DEF(m_wdt_timer_id);
    #define WDT_TIME_INTERVAL     APP_TIMER_TICKS(2000)
    /**
     * @brief WDT events handler.
     */
    void wdt_event_handler(void)
    {
    
    }
    /**
     * @brief WDT timer events handler.
     */
    static void m_wat_timeout_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    		nrf_drv_wdt_channel_feed(m_channel_id);
        //NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs
    }
    /**
     * @brief WDT feed.
     */
    void m_wat_feed(void)
    {
    		nrf_drv_wdt_channel_feed(m_channel_id);
        //NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs
    }
    /**
     * @brief WDT init.
     */
    void m_wdt_init(void)
    {
    		uint32_t err_code = NRF_SUCCESS;
        //Configure WDT.
        nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
        err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
        APP_ERROR_CHECK(err_code);
        err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
        APP_ERROR_CHECK(err_code);
        nrf_drv_wdt_enable();
    	
    		//Create timers.
        err_code = app_timer_create(&m_wdt_timer_id,
                                    APP_TIMER_MODE_REPEATED,
                                    m_wat_timeout_handler);
        APP_ERROR_CHECK(err_code);
    		
    		// Start application timers.
        err_code = app_timer_start(m_wdt_timer_id, WDT_TIME_INTERVAL, NULL);
        APP_ERROR_CHECK(err_code);
    }

  • BTW, if I don't define DEBUG, when I use app_error_fault_handler to reset system,I need to  shield NRF_BREAKPOINT_COND. 

    __WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
    {
        __disable_irq();
        NRF_LOG_FINAL_FLUSH();
    
    #ifndef DEBUG
        NRF_LOG_ERROR("Fatal error");
    #else
        switch (id)
        {
    #if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
            case NRF_FAULT_ID_SD_ASSERT:
                NRF_LOG_ERROR("SOFTDEVICE: ASSERTION FAILED");
                break;
            case NRF_FAULT_ID_APP_MEMACC:
                NRF_LOG_ERROR("SOFTDEVICE: INVALID MEMORY ACCESS");
                break;
    #endif
            case NRF_FAULT_ID_SDK_ASSERT:
            {
                assert_info_t * p_info = (assert_info_t *)info;
                NRF_LOG_ERROR("ASSERTION FAILED at %s:%u",
                              p_info->p_file_name,
                              p_info->line_num);
                break;
            }
            case NRF_FAULT_ID_SDK_ERROR:
            {
                error_info_t * p_info = (error_info_t *)info;
                NRF_LOG_ERROR("ERROR %u [%s] at %s:%u\r\nPC at: 0x%08x",
                              p_info->err_code,
                              nrf_strerror_get(p_info->err_code),
                              p_info->p_file_name,
                              p_info->line_num,
                              pc);
                 NRF_LOG_ERROR("End of error report");
                break;
            }
            default:
                NRF_LOG_ERROR("UNKNOWN FAULT at 0x%08X", pc);
                break;
        }
    #endif
    
    //    NRF_BREAKPOINT_COND;
        // On assert, the system can only recover with a reset.
    
    #ifndef DEBUG
        NRF_LOG_WARNING("System reset");
        NVIC_SystemReset();
    #else
        app_error_save_and_stop(id, pc, info);
    #endif // DEBUG
    }

  • Hi Taylor, 

    It's strange that it stopped at the break point. But when you test that did you use debug mode ? If you was debugging then it's expected that it stops at the NRF_BREAKPOINT_COND. 
    But it should not stop there if you are running the chip normally. 

    Which compiler&IDE are you using  ? 
    I did a quick test here with the ble_app_hrs and Segger Embedded Studio, trigger a fault and don't see that it stopped at the NRF_BREAKPOINT_COND. 

  • Which compiler&IDE are you using  ? 

    The IDE is Keil MDK5 and SDK17.2

    But it should not stop there if you are running the chip normally. 

    When I don't define DEBUG, RTT logger will print "Fatal error" and never restart when occur an error.

    After I shield  NRF_BREAKPOINT_COND, system will restart.

  • Hi again, 

    Please clarify how you test it. If you test it using debug mode (not by defining DEBUG, but the debug in KEIL) it will stop at the NRF_BREAKPOINT_COND. 

    Also please try to do a power reset when testing, the chip often stay in debug mode when first flashed. 

Related