nordic SDK 17.0.2 BLE DFU systemreset issue

My product currently has DFU (Device Firmware Update) functionality enabled, but I want to allow firmware updates only after receiving a specific command via BLE. This is to prevent unauthorized sources from updating the device with incorrect firmware.

My current approach is to execute the following procedure upon receiving a specific BLE command:

//NRF_POWER->GPREGRET = 0x01;
nrf_power_gpregret_set(0x01);
uint8_t aaa = nrf_power_gpregret_get();
NRF_LOG_INFO("Entering DFU mode = 0x% x",aaa);
//NVIC_SystemReset();
//nrf_delay_ms(1000);
nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_RESET);


If I don't write any value to gpregret, the system can reboot normally, and reading the value from gpregret works without any issues.
However, when I write a value to gpregret regardless of the method used—the system hangs after rebooting. Sometimes, continuous bootloader WDT messages appear.

I would like to ask if there’s a better approach to control whether DFU should be allowed.
In addition to the above issue, there's also the problem I mentioned earlier: disabling ble_dfu_buttonless_async_svci_init() causes BLE communication to stop working.
As for that issue, it seems that turning Bluetooth off and then back on again on the phone can resolve the problem—but this behavior is quite strange from a user’s perspective.

Thank you

Parents
  • Check bootloader source code. It may already have GPREGRET support compiled in. Did you try waiting the 2 or 3 minutes for a bootloader timeout?

  • The following is my bootloader:

    static void dfu_observer(nrf_dfu_evt_type_t evt_type)
    {
    switch (evt_type)
    {
    case NRF_DFU_EVT_DFU_FAILED:
    case NRF_DFU_EVT_DFU_ABORTED:
    case NRF_DFU_EVT_DFU_INITIALIZED:
    bsp_board_init(BSP_INIT_LEDS);
    bsp_board_led_off(BSP_BOARD_LED_0);
    bsp_board_led_on(BSP_BOARD_LED_1);
    bsp_board_led_off(BSP_BOARD_LED_2);
    break;
    case NRF_DFU_EVT_TRANSPORT_ACTIVATED:
    bsp_board_led_off(BSP_BOARD_LED_1);
    bsp_board_led_on(BSP_BOARD_LED_2);
    break;
    case NRF_DFU_EVT_DFU_STARTED:
    break;
    default:
    break;
    }
    }


    /**@brief Function for application main entry. */
    int main(void)
    {
    uint32_t ret_val;

    // Must happen before flash protection is applied, since it edits a protected page.
    nrf_bootloader_mbr_addrs_populate();

    // Protect MBR and bootloader code from being overwritten.
    ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE);
    APP_ERROR_CHECK(ret_val);
    ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE);
    APP_ERROR_CHECK(ret_val);

    (void) NRF_LOG_INIT(nrf_bootloader_dfu_timer_counter_get);
    NRF_LOG_DEFAULT_BACKENDS_INIT();
    NRF_LOG_RAW_INFO("\033[2J\033[;H. \033[2J")

    NRF_LOG_INFO("===Bootloader===");

    ret_val = nrf_bootloader_init(dfu_observer);
    APP_ERROR_CHECK(ret_val);

    NRF_LOG_FLUSH();

    NRF_LOG_ERROR("After main, should never be reached.");
    NRF_LOG_FLUSH();

    APP_ERROR_CHECK_BOOL(false);
    }
Reply
  • The following is my bootloader:

    static void dfu_observer(nrf_dfu_evt_type_t evt_type)
    {
    switch (evt_type)
    {
    case NRF_DFU_EVT_DFU_FAILED:
    case NRF_DFU_EVT_DFU_ABORTED:
    case NRF_DFU_EVT_DFU_INITIALIZED:
    bsp_board_init(BSP_INIT_LEDS);
    bsp_board_led_off(BSP_BOARD_LED_0);
    bsp_board_led_on(BSP_BOARD_LED_1);
    bsp_board_led_off(BSP_BOARD_LED_2);
    break;
    case NRF_DFU_EVT_TRANSPORT_ACTIVATED:
    bsp_board_led_off(BSP_BOARD_LED_1);
    bsp_board_led_on(BSP_BOARD_LED_2);
    break;
    case NRF_DFU_EVT_DFU_STARTED:
    break;
    default:
    break;
    }
    }


    /**@brief Function for application main entry. */
    int main(void)
    {
    uint32_t ret_val;

    // Must happen before flash protection is applied, since it edits a protected page.
    nrf_bootloader_mbr_addrs_populate();

    // Protect MBR and bootloader code from being overwritten.
    ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE);
    APP_ERROR_CHECK(ret_val);
    ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE);
    APP_ERROR_CHECK(ret_val);

    (void) NRF_LOG_INIT(nrf_bootloader_dfu_timer_counter_get);
    NRF_LOG_DEFAULT_BACKENDS_INIT();
    NRF_LOG_RAW_INFO("\033[2J\033[;H. \033[2J")

    NRF_LOG_INFO("===Bootloader===");

    ret_val = nrf_bootloader_init(dfu_observer);
    APP_ERROR_CHECK(ret_val);

    NRF_LOG_FLUSH();

    NRF_LOG_ERROR("After main, should never be reached.");
    NRF_LOG_FLUSH();

    APP_ERROR_CHECK_BOOL(false);
    }
Children
No Data
Related