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

nRF52 DK Failed to add BLE OTA DFU to the example project ble_app_uart

Hi, I'm using nRF52 DK. I'm following tutorial links 1, and 3 to learn how to add BLE OTA DFU to the example project ble_app_uart. 

Step 1

Following the above links, I created a new project called 1325.ble_app_uart_dfu.zip, which contains ble_app_uart and BLE OTA DFU functions. 

Step 2

build the \examples\ble_peripheral\ble_app_buttonless_dfu code to get the "ble_app_buttonless_dfu.hex"
build the \example\dfu\secure_bootloader code to get the "bootloader.hex"
build the our own application code to get the "ble_uart_ota.hex"

Step 3

In win10 cmd, use the following commands: 

nrfutil settings generate --family NRF52 --application ble_app_buttonless_dfu.hex --application-version 3 --bootloader-version 2 --bl-settings-version 2 settings.hex

nrfjprog --eraseall -f NRF52

nrfjprog --program s132_nrf52_7.2.0_softdevice.hex --verify -f NRF52

nrfjprog --program ble_app_buttonless_dfu.hex --verify -f NRF52

nrfjprog --program bootloader.hex --verify -f NRF52

nrfjprog --program settings.hex --verify -f NRF52

nrfjprog --reset -f NRF52

nrfutil pkg generate --application ble_uart_ota.hex --application-version 4 --hw-version 52 --sd-req 0x0101 --key-file priv.pem ble_uart_ota.zip


All files are 20211006 BLE OTA UART EXAMPLE.zip

Step 4

Now, on my mobile app nRF Connect, I could see a BLE signal named Nordic_Buttonless. I connected it and clicked the DFU button on the top right corner. Then, download my own firmware zip file to the nRF52 DK.

Then, I could see Nordic_Buttonless disconnects automatically. A new BLE signal named DFUTARG is connected. After a few seconds, DFUTARG disconnects automatically. Nothing else is connected. My own application BLE signal doesn't exist. 

Does anyone have any idea, please? Thanks a lot!  

Parents
  • Hi Steven, 

    I see some build error in your ble_app_uart_dfu. Maybe you can start from that. 

    You have to make sure your project  ble_app_uart_dfu can work You can program SD, Bootloader, setting and ble_app_uart_dfu to see it can work or not. If not, try to debug. You may get some help from searching "how to debug buttonless" or "ble_app_uart buttonless" on Devzon if it needs.  

    Regards,
    Amanda

  • Thank you for your help Amanda.

    My bootloader.hex works fine for the example project ble_app_buttonless_dfu, so I think bootloader.hex has no problem. After uploading SoftDevice and bootloader to the nRF52 DK, I "build and run" my own application ble_app_uart_dfu. The NRF_LOG_INFO() only prints a few information: 

     

    <info> app: Test 1
    <info> app: Test 2
    <info> app: Setting vector table to bootloader: 0x00078000

    I located the issue at: err_code = ble_dfu_buttonless_async_svci_init(); in the main loop. 

    /**@brief Application main function.
     */
    int main(void)
    {
        bool erase_bonds;
       // Initialize.
        uart_init();
        log_init();
        NRF_LOG_INFO("Test 1");
    
        // Initialize the async SVCI interface to bootloader before any interrupts are enabled.
        ret_code_t err_code;
        NRF_LOG_INFO("Test 2");
        err_code = ble_dfu_buttonless_async_svci_init();
        NRF_LOG_INFO("Test 3");
        APP_ERROR_CHECK(err_code);
    
        
    
        timers_init();
        buttons_leds_init(&erase_bonds);
        power_management_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        advertising_start();
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
            
        }
    }
    
    
    

    So I "go to the definition" of ret_val = nrf_dfu_svci_vector_table_set();, and found the application stucks at err_code = sd_softdevice_vector_table_base_set(bootloader_addr); in nrf_dfu_svci.c file. 

    I followed the exact same steps as the tutorials. But still got this error. I have no clue at all about the solution.

    1) Do you have any clue, please?

    2) Did I have the right steps (upload SD+bootloader to nRF52, then build and run the custom application ble_app_uart_dfu)? 

    Thank you very much. 

  • Hi, 

    Not sure where is wrong with your project, but the basic rules are as the following:

    1. Add source code to nRF_DFU folder:
    <sdk>\components\ble\ble_services\ble_dfu\ble_dfu.c
    <sdk>\components\ble\ble_services\ble_dfu\ble_dfu_bonded.c
    <sdk>\components\ble\ble_services\ble_dfu\ble_dfu_unbonded.c
    <sdk>\components\libraries\bootloader\dfu\nrf_dfu_svci.c

    2. Add DFU headfile User Include Directories:
    ../../../../../../components/libraries/bootloader
    ../../../../../../components/libraries/bootloader/ble_dfu
    ../../../../../../components/libraries/bootloader/dfu
    ../../../../../../components/libraries/svc

    3. Modify sdk_config.h:
    BLE_DFU_ENABLED 1
    NRF_SDH_BLE_VS_UUID_COUNT  2  //increase

    4. Add the following Preprocessor Defines:
    NRF_DFU_SVCI_ENABLED
    NRF_DFU_TRANSPORT_BLE=1
    BL_SETTINGS_ACCESS_ONLY

    5. Includ the following file in main.c: 
    #include “nrf_dfu_ble_svci_bond_sharing.h”
    #include “nrf_svci_async_function.h”
    #include “nrf_svci_async_handler.h”
    #include “ble_dfu.h”
    #include “nrf_power.h”
    #include “nrf_bootloader_info.h”

    6. Add the following functions from ble_app_buttonless_dfu example to main.c
    static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event){};
    NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);
    static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context){};
    NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) = {};
    static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event){};

    7. Initialize DFU buttonless service in main.c/services_init

        ble_dfu_buttonless_init_t dfus_init = {0};
    
        // Initialize DFU buttonless.
        dfus_init.evt_handler = ble_dfu_evt_handler;
    
        err_code = ble_dfu_buttonless_init(&dfus_init);
        APP_ERROR_CHECK(err_code);

    8. Initialized the async SVIC interface in main()

        // Initialize the async SVCI interface to bootloader before any interrupts are enabled.
        err_code = ble_dfu_buttonless_async_svci_init();
        APP_ERROR_CHECK(err_code);

    9. Compile with debug mode and refer RTT log to modify RAM_START and RAM_SIZE. 

    --

    Command for programming app with dfu_buttonless.  

    nrfjprog --eraseall
    mergehex -m s132_nrf52_7.2.0_softdevice.hex secure_bootloader_ble_s132_pca10040_debug.hex -o SD_BL.hex
    nrfjprog --program SD_BL.hex --chiperase -r
    nrfutil settings generate --family NRF52 --application ble_app_uart_pca10040_s132.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 settings.hex
    mergehex -m ble_app_uart_pca10040_s132.hex settings.hex -o merged.hex
    nrfjprog --program merged.hex --sectorerase -r

    Command for updating with DFU package

    nrfjprog --eraseall
    mergehex -m s132_nrf52_7.2.0_softdevice.hex secure_bootloader_ble_s132_pca10040_debug.hex -o SD_BL.hex
    nrfjprog --program SD_BL.hex --chiperase -r
    nrfutil pkg generate --application ble_app_uart_pca10040_s132.hex --application-version 4 --hw-version 52 --sd-req 0x0101 --key-file priv.pem ble_uart_ota.zip

    Here is the ble_app_uart_buttonless_dfu.zip which I add buttonless_dfu to ble_app_uart. FYI.

    Regards,
    Amanda

Reply
  • Hi, 

    Not sure where is wrong with your project, but the basic rules are as the following:

    1. Add source code to nRF_DFU folder:
    <sdk>\components\ble\ble_services\ble_dfu\ble_dfu.c
    <sdk>\components\ble\ble_services\ble_dfu\ble_dfu_bonded.c
    <sdk>\components\ble\ble_services\ble_dfu\ble_dfu_unbonded.c
    <sdk>\components\libraries\bootloader\dfu\nrf_dfu_svci.c

    2. Add DFU headfile User Include Directories:
    ../../../../../../components/libraries/bootloader
    ../../../../../../components/libraries/bootloader/ble_dfu
    ../../../../../../components/libraries/bootloader/dfu
    ../../../../../../components/libraries/svc

    3. Modify sdk_config.h:
    BLE_DFU_ENABLED 1
    NRF_SDH_BLE_VS_UUID_COUNT  2  //increase

    4. Add the following Preprocessor Defines:
    NRF_DFU_SVCI_ENABLED
    NRF_DFU_TRANSPORT_BLE=1
    BL_SETTINGS_ACCESS_ONLY

    5. Includ the following file in main.c: 
    #include “nrf_dfu_ble_svci_bond_sharing.h”
    #include “nrf_svci_async_function.h”
    #include “nrf_svci_async_handler.h”
    #include “ble_dfu.h”
    #include “nrf_power.h”
    #include “nrf_bootloader_info.h”

    6. Add the following functions from ble_app_buttonless_dfu example to main.c
    static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event){};
    NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);
    static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context){};
    NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) = {};
    static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event){};

    7. Initialize DFU buttonless service in main.c/services_init

        ble_dfu_buttonless_init_t dfus_init = {0};
    
        // Initialize DFU buttonless.
        dfus_init.evt_handler = ble_dfu_evt_handler;
    
        err_code = ble_dfu_buttonless_init(&dfus_init);
        APP_ERROR_CHECK(err_code);

    8. Initialized the async SVIC interface in main()

        // Initialize the async SVCI interface to bootloader before any interrupts are enabled.
        err_code = ble_dfu_buttonless_async_svci_init();
        APP_ERROR_CHECK(err_code);

    9. Compile with debug mode and refer RTT log to modify RAM_START and RAM_SIZE. 

    --

    Command for programming app with dfu_buttonless.  

    nrfjprog --eraseall
    mergehex -m s132_nrf52_7.2.0_softdevice.hex secure_bootloader_ble_s132_pca10040_debug.hex -o SD_BL.hex
    nrfjprog --program SD_BL.hex --chiperase -r
    nrfutil settings generate --family NRF52 --application ble_app_uart_pca10040_s132.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 settings.hex
    mergehex -m ble_app_uart_pca10040_s132.hex settings.hex -o merged.hex
    nrfjprog --program merged.hex --sectorerase -r

    Command for updating with DFU package

    nrfjprog --eraseall
    mergehex -m s132_nrf52_7.2.0_softdevice.hex secure_bootloader_ble_s132_pca10040_debug.hex -o SD_BL.hex
    nrfjprog --program SD_BL.hex --chiperase -r
    nrfutil pkg generate --application ble_app_uart_pca10040_s132.hex --application-version 4 --hw-version 52 --sd-req 0x0101 --key-file priv.pem ble_uart_ota.zip

    Here is the ble_app_uart_buttonless_dfu.zip which I add buttonless_dfu to ble_app_uart. FYI.

    Regards,
    Amanda

Children
  • Thanks a lot Amanda. 

    We have successfully added OTA to our custom application. Plz note that: 

    For Step 8: remember to add the code after BLE service initialize inside main() in main.c

    For Step 9: after debug->go, you will see the RAM_SIZE and RAM_START correction message. Change them. Debug->go again. You will see the RAM_SIZE and RAM_START message disapears, and you will see a new error message: no bootloader. It's OK, ignore it. Build the project, and continue on step 10 and 11. It's same as Noric BLE buttonless OTA example. When OTA function is included, you cannot simply build and run the Noric BLE buttonless OTA example. You must merge with bootloader, bootloader setting, and softdevice together. 

    Also, when you merge the files, the file sequence is vital! It's due to the memery allocation inside the chip. softdevice->bootloader->bootloader settings->your own firmware. 

    Good luck for other people! 

Related