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

DFU compatibility for a mesh example

Hi,

I am interested to know how to make a mesh node (for example, a light server) compatible to perform a DFU.

I have gone through the DFU page and I noticed that the DFU is done over the Serial port. I understand that the dfu firmware is being replaced with blinky firmware. Correct me if I am wrong.

Now, what changes should I make to the commands inorder to make the light_server example node to be DFU compatible/capable over the air?

Would replacing the application hex file on step 8 to light_server instead of dfu solve it? or should I add any other commands to have light_server firmware first?

Thank you.

Parents
  • Hello,

    well. The short answer is that you need the mesh_evt_handler() to handle DFU packets, like it does in the DFU example. In addition, if you want the device to handle Serial DFU (the one who receives the packets from nrfutil), you need it to support serial DFU as well. 

    This is done in nrf_mesh_serial_init(NULL); in mesh_init(void).

    Inside this call, serial_handler_dfu_init() is called, which handles the DFU serial messages.

    When you try to include the DFU packets (over Mesh) you will probably have to include everything you need around as well. Give it a go, and let me know if you get stuck.

    BR,

    Edvin

  • Hi,

    The short answer is that you need the mesh_evt_handler() to handle DFU packets, like it does in the DFU example.

    I notice that nrf_mesh_evt_handler_t is used in only few examples like EnOcean, light switch provisioner, Lpn examples. 

    So, in order to make other examples DFU capable, I need to add the nrf_mesh_evt_handler while mesh initilization.

    Give it a go, and let me know if you get stuck.

    If I am trying to push the dfu packets over the air but not serial, I should push it from the nrf connect app right? or can we do it from the mesh app? Sorry but I have no idea about how to push it OTA!!

    Thank you.

  • You need to check out the defines that i mentioned in the previous reply. TIMER_DATA_TIMEOUT_US and TIMER_START_TIMEOUT_US.

    I found these and they are both around 10seconds and 50 seconds respectively. I am waiting for few minutes between each push.

    The application that is stored is already up to date. You need to increase the application version to make the device accept it.

    I am sure that the version number is increased as I can see the version number in the DFU messages exchanged before the push.

    The device is still expecting the next packet from a previous session because TIMER_DATA_TIMEOUT_US has not timed out and TIMER_START_TIMEOUT_US has not timed out.

    I don't think that this might be the case because the customized application that I have advertises its name and I can see the name change on the node after the DFU is successfully pushed. Similarly I added a command for LED's to blink after loading the new FW on DFU example so that it gives me an indication of successful DFU transfer and updating the firmware. 

    Please open a new ticket so that one of the guys in the office can check. 

    Okay. I will try this.

    While going through all this, I just programmed the dev board with DFU example in Mesh SDK3.1.0 using Segger embedded studio. I noticed this which I feel is weird.

    Are the logs supposed to look like this?

  • It shouldn't print that in an unmodified example/SDK.

    Can you try with a clean SDK, download and unzip from here.

    Maybe you have defined "HOST" in some file in another project that affects the DFU example. If you look in nrf_meshdfu_init() in nrf_mesh_dfu.c, it will set the dfu_cmd_handler if "HOST" is not defined. So if it is defined, this cmd handler is never set, and you will get the error that you are currently seeing.

    Try with an unmodified SDK. If that works, try to open your custom project in this SDK, and see if it behaves the same.

  • Okay.

    Finally I was able to have the DFU working. It looks like the size of the DFU was an issue. I was pushing the image created using the hex file generated in debug mode. I tried it with the hex file built in release mode along with the patch given by your colleague in this thread.

     Now, I changed the company ID from nordic's to our own company ID. It fails to push.
    If I try to push it with Nordic's company ID, the DFU is successful.

    I changed the CompanyID in the FW(access.h), device page. Tried to push the update(with new Company ID) which failed replying back ERROR_INVALID_DATA.

    Is there any hardcoded information in the nrfutil tool or somewhere else where we need to add new Company ID's?

    Or what might be the reason that the update fails when I push with a company ID which isn't Nordic's?

  • DeveloperZ said:
    Is there any hardcoded information in the nrfutil tool or somewhere else where we need to add new Company ID's?

     No. There isn't. I tested it on my desk now, and you can use whatever company ID you like from a software point of view. Licencing is a different story. 

    I suggest that you write a bat script to generate all the files, and perform the DFU. This way you are certain that you don't forget to update a file. The only exception is that you need to update the bootloader_config_default.json file manually. 

    I use this script:

    REM nrfutil keys --gen-key keys\private_key.txt
    REM nrfutil keys --show-vk hex keys\private_key.txt
    REM Remember to update the bootloader_config_default.json file with the key you are using. Also use the same company-id that you use in nrfutil dfu genpkg.
    
    
    cd tools\dfu
    python device_page_generator.py -d nrf52832_xxAA -sd "s132_6.1.0"
    cd ..\..
    
    
    nrfutil dfu genpkg --application ..\..\bin\blinky\blinky_nrf52832_xxAA_s132_6.1.0.hex --company-id 0x00000060 --application-id 1 --application-version 2 --key-file keys\private_key.txt --sd-req 0x00AF --mesh dfu_test.zip
    
    
    
    
    
    nrfjprog -e --snr 682654319
    nrfjprog -e --snr 682499544
    
    nrfjprog --program ..\..\bin\softdevice\s132_nrf52_6.1.0_softdevice.hex --verify --snr 682654319
    nrfjprog --program ..\..\bin\softdevice\s132_nrf52_6.1.0_softdevice.hex --verify --snr 682499544
    
    nrfjprog --program ..\..\bin\bootloader\gccarmemb\mesh_bootloader_gccarmemb_nrf52832_xxAA.hex --verify --snr 682654319
    nrfjprog --program ..\..\bin\bootloader\gccarmemb\mesh_bootloader_gccarmemb_nrf52832_xxAA.hex --verify --snr 682499544
    
    nrfjprog --program build\dfu_nrf52832_xxAA_s132_6.1.0_Debug\dfu_nrf52832_xxAA_s132_6.1.0.hex --verify --snr 682654319
    nrfjprog --program build\dfu_nrf52832_xxAA_s132_6.1.0_Debug\dfu_nrf52832_xxAA_s132_6.1.0.hex --verify --snr 682499544
    
    nrfjprog --program tools\dfu\bin\device_page_nrf52832_xxAA_s132_6.1.0.hex --verify --snr 682654319
    nrfjprog --program tools\dfu\bin\device_page_nrf52832_xxAA_s132_6.1.0.hex --verify --snr 682499544
    
    nrfjprog --reset --snr 682654319
    nrfjprog --reset --snr 682499544
    
    TIMEOUT 5
    
    nrfutil dfu serial -pkg dfu_test.zip -p COM7 -b 115200 -fc --mesh

    I copied the tools folder from the SDK root folder inside the examples\dfu folder. I also have the bat-script above in this folder. 

    If it fails, there are a few steps you can check yourself. 

    1: Check the RTT log of the device that you try to update. Does it give any useful information?

    2: Use the verbose dfu command, and see what the nRF responds. Check out the links that I provided earlier regarding the serial commands:

     

    Edvin said:
    Please check out the Serial commands, Serial events and Serial status codes in the mesh sdk documentation.
  • Also, note that the bootloader_onfig_default.json takes the company-id in decimal, and the nrfutil pkg generate command uses the hexadecimal representation of the company ID. 

Reply Children
  • Hi,

    When I made another post that I was unable to make repeated DFU, I was given a patch which calculates the size of the bank. It worked for a while and now I can't do the DFU after first update AGAINNN.

    I even tried to do DFU without keys but the result was the same. I think that it is something to do with the files. Something is changing after first update which isn't allowing me to push the second update.

    By any chance, would there be in anything wrong with the boards if I keep on doing DFU for weeks?

  • DeveloperZ said:
    It worked for a while and now I can't do the DFU after first update AGAINNN.

     What did you do in between?

    Can you try to run the DFU with the dfu example from the SDK? Use this example as your DFU image. Does the same issue occur if you do this?

Related