nrf52832 OTA over ESB based on SDK17.1.0

Hi everyone:    I developed an application based on ESB wireless communication protocol ofr the nRF52832, and I would like to perform an OTA DFU with it.    Do you know any example of some over the air FW upgrade of nRF52832 chip via ESB protocol.

    SDK is 17.1.0.

Best regards,

Lurn.

Parents
  • I only found examples of ble and uart in the dfu/secure_bootloader folder, Which one should I use or how should I modify it to adapt my program.

  • Hello,

    It is correct that you will only find BLE and UART in our samples, but I know that several customers have ported this to SPI, so if you need it over ESB, then that should also be possible. The transport layers in the bootloader for the nRF5 SDK are on purpose quite separated from the rest of the libraries, to make it easier to change the transport layer, or to add your own transport layer.

    But you do need to implement it yourself. Also note that we do not have the "DFU Master" as an official part of our SDK. We have tools like nrfutil (open source) or nRF Connect for Desktop (not open source), and applications for mobile phones that are open source (but mobile phones doesn't have ESB). However, there is an unofficial implementation (not properly tested. You can use it, but on your own "risk"), which you can find here. I have not tested these myself, but you can give it a go. I suggest you test out the UART master, in combination with the uart bootloader, and then you can port both to ESB once you are up and running.

    Best regards,

    Edvin

  • Hi Edvin

    If I don't want to use nrfutil do you guys have any other example for me to update the version?

    And how can I get or set the firmware version in my program?

    Best Regards

    Lurn

  • Hello Lurn,

    Sorry for the late reply. I have been on vacation. 

    It seems like this ticket got the status "verified answer" before your last reply, meaning it disappeared from my list. Did you solve the issue from about 1 month ago?

    Regarding your last question.

    nrfutil is the only officially supported tool that we have. However, it is open source, and you can find the source code on GitHub.

    We do have an experimental implementation for the DFU master (the device that sends the packet) over UART, so perhaps you can look into that. It is found in the getting started with nRF5 SDK DFU blog post. Search for "DFU Master code".

    However, you probably still want to use nrfutil to generate your images. This is also where you set the firmware version. By default, this version is not stored in the application itself, but in the bootloader settings, which are generated when you do the DFU. So it is part of the DFU image, but not the application (meaning the application is not aware of what version it is running). If you need the application to know, you need to hard code this into your application (as a #define). 

    Best regards,

    Edvin

  • Hi Edvin,

    It seems like this ticket got the status "verified answer" before your last reply, meaning it disappeared from my list. Did you solve the issue from about 1 month ago?

    Yes, I can update via uart now.

    I was found the source code on GitHub, but it is implemented in python and contains library files, I want to use it on ARM, it doesn't seem feasible.

    And yes I still want to use nrfutil because I have to set the firmware version.

    if there is no other way, I will try to use BLE to update.

    If I use BLE to upgrade, and my main application is used ESB, will the two of them conflict?

    Best regards,

    Lurn

  • Lurn_Z said:
    If I use BLE to upgrade, and my main application is used ESB, will the two of them conflict?

    Not other than that the softdevice will have to be present in flash. You don't need to enable it in your application.

    So your first step before trying to perform a DFU would be to make sure that your application runs as intended when the softdevice is present in the flash of the nRF52. Just to make sure that you have the correct start addresses for both RAM and Flash in your application.

    Best regards,

    Edvin

  • Hi Edvin,

    For my application, How could I modify the address? I don't know where the softdevice end address is.

    The ble bootloader debug address is here.

    and the application address is here.

    and if I use ble bootloader do i still need to program the mbr.hex?

    Best regards,

    Lurn

Reply Children
  • Hello,

    The bootloader address settings you can leave as is, but you need to adjust the flash (IROM1) address and size for your application. 

    Assuming you are still using SDK17.1.0, and a BLE bootloader, I assume you are using s132_nrf52_7.2.0_softdevice.hex. Just look at any of the samples using the same softdevice, such as the ble_app_hrs\pca10040\s132\ and open the project settings. You should see that it uses start address 0x26000, and size 0x5A000. 

    Strictly speaking, we don't have a size of 5A000, because the bootloader takes up address 0x71000 to 0x80000, so you can set start address 0x26000 and size 0x4B000

    But it wouldn't be an issue unless your application is so big that it starts growing into your bootloader. 

    The IRAM1 settings (RAM settings) you can leave as is. The softdevice requires 8 bytes (the same as MBR) if you do not enable it in your application.

    Lurn_Z said:
    and if I use ble bootloader do i still need to program the mbr.hex?

    No, if you program the softdevice, you don't need to program the mbr.hex. The MBR is merged into the softdevice. 

    Best regards,

    Edvin

  • Hi Edvin,

    I use the bootloader_ble_s132_pca10040_debug to build the bootloader.

    Then I use this cmd to program it.

    nrfutil settings generate --family NRF52 --application app.hex --application-version 0 --bootloader-version 0 --bl-settings-version 2 settings.hex
    
    nrfjprog --eraseall -f NRF52
    nrfjprog --program s132_nrf52_7.2.0_softdevice.hex --verify -f NRF52
    nrfjprog --program bootloader.hex --verify -f NRF52
    nrfjprog --program app.hex --verify -f NRF52
    nrfjprog --program settings.hex --verify -f NRF52
    nrfjprog --reset -f NRF52

    Strictly speaking, we don't have a size of 5A000, because the bootloader takes up address 0x71000 to 0x80000, so you can set start address 0x26000 and size 0x4B000

    But it wouldn't be an issue unless your application is so big that it starts growing into your bootloader. 

    The IRAM1 settings (RAM settings) you can leave as is. The softdevice requires 8 bytes (the same as MBR) if you do not enable it in your application.

    I set the application start address to 0x26000 adn size is 0x4B000, Since I'm not using bluetooth just ESB in my application, no other modifications about the RAM/ROM.

    To enter the DFU mode, I use the NRF_POWER_GPREGRET register.

    #define BOOTLOADER_DFU_GPREGRET_MASK                 (0xF8)      /**< Mask for GPGPREGRET bits used for the magic pattern written to GPREGRET register to signal between main app and DFU. */
    #define BOOTLOADER_DFU_GPREGRET                      (0xB0)      /**< Magic pattern written to GPREGRET register to signal between main app and DFU. The 3 lower bits are assumed to be used for signalling purposes.*/
    #define BOOTLOADER_DFU_START_BIT_MASK                (0x01)      /**< Bit mask to signal from main application to enter DFU mode using a buttonless service. */
    #define BOOTLOADER_DFU_START    (BOOTLOADER_DFU_GPREGRET | BOOTLOADER_DFU_START_BIT_MASK)      /**< Magic number to signal that bootloader should enter DFU mode because of signal from Buttonless DFU in main app.*/
    
    
    static void enter_dfu_mode(void)
    {
        uint8_t old_gpregret = nrf_power_gpregret_get();
        UART_PRINTF("get the old_gpregret = %d", old_gpregret);
        uint8_t temp = 0;
    
        nrf_power_gpregret_set(BOOTLOADER_DFU_START);
        while((temp & BOOTLOADER_DFU_START) != BOOTLOADER_DFU_START)
        {
            temp = nrf_power_gpregret_get();
            UART_PRINTF("temp = %d", temp);
        }
        UART_PRINTF("nrf_pwr_mgmt_shutdown NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU and system reset.");
        nrf_delay_ms(10);
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
        NVIC_SystemReset();
    }

    I get the log over RTT shows "nrf_pwr_mgmt_shutdown NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU and system reset", then I reconnect the RTT it shows

    00> In nrf_bootloader_init
    00> Calling nrf_dfu_settings_init()...
    00> Initializing nrf_fstorage_nvmc backend.
    00> Using settings page.
    00> Copying forbidden parts from backup page.
    00> Destination settings are identical to source, write not needed. Skipping.
    00> Backing up settings page to address 0x7E000.
    00> Destination settings are identical to source, write not needed. Skipping.
    00> Enter nrf_bootloader_fw_activate
    00> No firmware to activate.
    00> CRC check of app failed. Return 1
    00> App is valid
    00> DFU mode requested via GPREGRET.
    00> WDT is not enabled
    00> in weak nrf_dfu_init_user
    00> timer_stop (0x20005980)
    00> timer_activate (0x20005980)
    00> Entering DFU mode.
    00> Initializing transports (found: 1)
    00> Initializing BLE DFU transport
    00> Setting up vector table: 0x00071000
    00> Enabling SoftDevice.
    00> State request: 0x00000000
    00> Notify observer 0x0007C9E8 => ready
    00> State change: 0x00000000
     

    but I can't find the ble name via nrf_connect on my phone. I didn't change the name, so the name should be "DfuTarg"

    #ifndef NRF_DFU_BLE_ADV_NAME
    #define NRF_DFU_BLE_ADV_NAME "DfuTarg"
    #endif

    Can you please tell me where I am wrong?

    Best regards,

    Lurn

  • Hello Lurn,

    NRF_DFU_BLE_REQUIRES_BONDS is set to 0 in your bootloader's sdk_config.h file, right?

    If it is not set to 0, try to set it to 0. If it is set to 0, please try to debug ble_dfu_transport_init() in nrf_dfu_ble.c.

    Does the line:

    if (nrf_dfu_settings_adv_name_is_valid())

    return true? (you can simply add a log line using NRF_LOG_INFO(); and it will pop up in the log that you pasted)). 

    Also check if the line:

        if ((m_flags & DFU_BLE_FLAG_USE_ADV_NAME) != 0)

    in gap_params_init() returns true. If it does, it will use a different advertising name. 

    Let us start with those, and take it from there, depending on what you see.

    Best regards,

    Edvin

  • Hello Edvin,

    I'm so sorry for finding out that I've entered a misunderstanding.

    Originally I was saying that I need to upgrade via UART, and yes it worked, but But after I finished testing, my colleague told me that we are using ARM architecture, so I can't update my nrf-device by use nrfutil, Because the source code has some libraries that cannot be ported to the host device.

    So I wanted to use the bluetooth update and ask you a lot of questions about it, but when I finished work yesterday and asked my colleague about bluetooth related things ready to debug the bluetooth upgrade, he told me that our host device does not have bluetooth enabled (I Know that our host device has bluetooth, but I don't know it won't be used).

    Sorry for taking up so much of your time with these wrong questions.

    Let me sort out the current situation.

    1. I can enter the DFU mode normally.

    2. I can update success via UART on PC.

    3. I can't port the ntfutil to host device, because it use ARM.

    4. Since 3 is not established, I can't upgrade nrf-device on the host device.

    So I think the question should be how to update nrf-device without ntfutil.

    And I think there is a method like this:

    I can receive the update file and save it to bank1, then enter the DFU mode, it will check and update itself.

    But I don't know how to receive the file and save it to bank1.

    I found an example made by Vidar, but it also used nrfutil.

    Apologies again for the previous question.

    Best regards,

    Lurn

  • No worries, Lurn,

    What you are writing makes sense to me! So we are back at having a UART bootloader without the possibility to use nrfutil, if I understand correctly.

    However, you could still use nrfutil to generate the DFU images on a computer, and then somehow transfer that to the computer that will transfer the image to the nrf-device, right?

    In that case, you would only need the ARM device to run the part of nrfutil that does the transfer, which is only a small part of nrfutil.

    While we do not have a strip down version of nrfutil, the colleague that wrote the getting started with DFU guide also wrote a sample application that can run on another nRF device, and will update the target nRF device over UART. Click that link, and search for "DFU Master Code". 

    I believe it may be easier to analyze and reverse engineer the process from that sample than it is to interpret the nrfutil source code.

    Unfortunately, we don't have very much good documentation on nrfutil, but a couple of useful links are:

    A general description of the DFU procedure can be found here.

    The UART Serial protocol is described here.

    Just in case, the link to nrfutil source code. But I find it difficult to navigate to understand the protocol.

    Lastly, one additional hint could be to hook on a UART to computer sniffer/analyzer, and observe an update, to see if you can make sense of the packets, as described in the links above.

    Best of luck!

    Best regards,

    Edvin

Related