nrf beacon can not enter bootloader from application

Hi support team,

I have a nrf 51822 beacon black version and developing with nRF5SDK1230. i'm learning about update firmware for it over BLE. i try to run example dfu/bootloader_sercure and create zip file by using nrfutil command. First i erase flash by jlink tool, program s130_nrf51_2.0.1_softdevice and bootloader_sercure example. then i use nrf connect app with usb dongle for updating firmware. the process is good, i can enter to my app. But then, in my application, i try to jump to bootloader by command NRF_POWER->GPREGRET = 0xB1; and call reset function, but it can not enter bootloader. i don't know why so i need your help. 

Here is my config

Parents
  • Hi,

    The first thing that comes to mind as the application works but this fails when you try to enter DFU mode in the bootloader  is that the default example bootloader enables the 32.768 kHz crystal, but many simple boards does not have the 32.768 kHz crystal. In that case, the sdk_config.h of the bootloader must be adjusted to use internal RC instead of the crystal. Have you checked that?

  • as i said, first beacon is in boot mode, and then i use dfu to update firmware. there is a 32768 crystals on board and it works

  • I see, I read your question too quickly. The issue is just with entering bootloader mode from application, then. Have you modified the bootloader? If not, the approach with writing a magic word to GPREGRET does not work, as it is not read by the bootloader in SDK 12.3, which has another approach for buttonless DFU. Unless you have changed this in the bootloader you need to write to the bootloader settings page to enter DFU mode, as is done by the buttonless BLE DFU service implementation in components\ble\ble_services\ble_dfu\ble_dfu.c.

  • Hi I found this thread https://devzone.nordicsemi.com/f/nordic-qa/38611/setting-up-ota-for-sdk12, he used the same way to enter bootloader NRF_POWER -> GREGRET = 0xB1, but it's not work with sdk12.3. you said i need to change the bootloader, write something to the settings page. Can you send me some simple code to enter bootloader from app. Thanks

  • Hi,

    I suggest you refer to ble_dfu.c, which implements this. For only the part that enters DFU mode, see how enter_bootloader() sets  s_dfu_settings.enter_buttonless_dfu = true and then calls nrf_dfu_settings_write() to write this to flash. Note that if you want a complete example that use this for buttonless DFU you can refer to the Experimental: Buttonless DFU Template Application.

    Alternatively you can modify the bootloader to use GPREGRET instead, as is done in newer SDK versions. That is a very simple mechanism where you write to the GPREGRET in the application and read it in the bootloader. Remember that it is static and must be explicitly cleared. To see how this can be done, you can check a newer SDK example. Essentially you would just need to add a check in the bootloader in nrf_dfu_enter_check() in nrf_dfu.c, in the same was as a GPIO pin is read.

  • Thanks Thorsrud, I was deep checking nrf libraries. For everyone, you guy can use as easiest sample to enter bootloader from app using sdk12.3

    #include "nrf_dfu_settings.h"
    #include "crc32.h"
    #include "nrf_nvmc.h"
    
    uint8_t  m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS)))
                                                   __attribute__((used));
    nrf_dfu_settings_t s_dfu_settings;
    
    //boot function
    static uint32_t nrf_dfu_settings_calculate_crc(void)
    {
        // the crc is calculated from the s_dfu_settings struct, except the crc itself and the init command
        return crc32_compute((uint8_t*)&s_dfu_settings + 4, sizeof(nrf_dfu_settings_t) - 4 - sizeof(s_dfu_settings.init_command), NULL);
    }
    
    void enter_boot(void) {
    	s_dfu_settings.enter_buttonless_dfu = true;
    	s_dfu_settings.crc = nrf_dfu_settings_calculate_crc();
    	
    	nrf_nvmc_page_erase(BOOTLOADER_SETTINGS_ADDRESS);
    	nrf_nvmc_write_bytes(BOOTLOADER_SETTINGS_ADDRESS, (void*)&s_dfu_settings, sizeof(nrf_dfu_settings_t));
    }
    


Reply
  • Thanks Thorsrud, I was deep checking nrf libraries. For everyone, you guy can use as easiest sample to enter bootloader from app using sdk12.3

    #include "nrf_dfu_settings.h"
    #include "crc32.h"
    #include "nrf_nvmc.h"
    
    uint8_t  m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS)))
                                                   __attribute__((used));
    nrf_dfu_settings_t s_dfu_settings;
    
    //boot function
    static uint32_t nrf_dfu_settings_calculate_crc(void)
    {
        // the crc is calculated from the s_dfu_settings struct, except the crc itself and the init command
        return crc32_compute((uint8_t*)&s_dfu_settings + 4, sizeof(nrf_dfu_settings_t) - 4 - sizeof(s_dfu_settings.init_command), NULL);
    }
    
    void enter_boot(void) {
    	s_dfu_settings.enter_buttonless_dfu = true;
    	s_dfu_settings.crc = nrf_dfu_settings_calculate_crc();
    	
    	nrf_nvmc_page_erase(BOOTLOADER_SETTINGS_ADDRESS);
    	nrf_nvmc_write_bytes(BOOTLOADER_SETTINGS_ADDRESS, (void*)&s_dfu_settings, sizeof(nrf_dfu_settings_t));
    }
    


Children
No Data
Related