This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Changes to the application for DFU

I am using SDK17, nRF52840 based custom board and SoftDevice 7.2.0 with SES.

I want to use SDK's secure bootloader (pca10056_s140_ble) with my own keys.

To enter to the bootloader I need to perform these functions and I have added them to my code.

err_code = sd_power_gpregret_clr(0, 0xffffffff);
APP_ERROR_CHECK(err_code);

err_code = sd_power_gpregret_set(0, 0xB1);
APP_ERROR_CHECK(err_code);

nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);

On bootup, the device shows up as DfuTarg, I can connect to it, upload the ZIP and the device runs perfectly. But to perform another OTA, when I connect to my own service and perform the above-given code portion, the device hangs. It does not enter DFU(I verified it by toggling an LED at the start of the bootloader ).

What else do I need to change in my application? As far as I know, I can not debug my application as there is a bootloader.

Parents
  • Hello,

    Are you sure the gpregret register is actually set after the reset?  Try adding a check before you shut down, because these writes may take some time. Even after returning, it may not be complete.

    err_code = sd_power_gpregret_clr(0, 0xffffffff);
    APP_ERROR_CHECK(err_code);
    
    err_code = sd_power_gpregret_set(0, 0xB1);
    APP_ERROR_CHECK(err_code);
    
    uint32_t gpregret_read_value = 0x00000000;
    while (gpregret_read_value != 0xB1)
    {
        err_code = sd_power_gpregret_get(0, &gpregret_read_value);
    }
    
    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);

    After trying this, then test out the _debug bootloader project (pca10056_s140_ble_debug), and monitor the RTT log. What does the log say in dfu_enter_check():

    static bool dfu_enter_check(void)
    {
        if (!app_is_valid(crc_on_valid_app_required()))
        {
            NRF_LOG_DEBUG("DFU mode because app is not valid.");
            return true;
        }
    
        if (NRF_BL_DFU_ENTER_METHOD_BUTTON &&
           (nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 0))
        {
            NRF_LOG_DEBUG("DFU mode requested via button.");
            return true;
        }
    
        if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
           (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
        {
            NRF_LOG_DEBUG("DFU mode requested via pin-reset.");
            return true;
        }
    
        if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
           (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
        {
            NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
            return true;
        }
    
        if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
           (s_dfu_settings.enter_buttonless_dfu == 1))
        {
            NRF_LOG_DEBUG("DFU mode requested via bootloader settings.");
            return true;
        }
    
        return false;
    }

    You can also set a breakpoint in:

        if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
           (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
        {
            NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
            return true;
        }

    And check what the gpregret is set to.

    BR,

    Edvin

  • Hello Edvin,

    Thanks for replying.

    Pardon me as I had an altogether different problem. I had NRF_LOG_ENABLED set to 1 which caused the problem when NRF_LOG_FINAL_FLUSH() was being called.

    Yet, your suggestion is useful (implemented as well) as shutting down the system before the GPREGRET register have been set can cause problem sometimes.

    Regards,

    Vishwas

Reply Children
No Data
Related