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.

  • Hi,

    I was able to successfully add the DFU capabilities into the Enocean_switch node, I was able to push the Blinky dfu to it and it was done successfully. Then, I tried to push a DFU packet with a customized mesh example hex file which understandably takes around 90mins.

    Next, I am thinking about differentiating the DFU packets as my network might have multiple firmwares. 
    My best idea is differentiating the application id in the bootloader.json file. Is there any other way(can be easy or not) to differentiate the firmware updates.

    Feel free to criticize my ideas and point out the best way.

    Thank you. 

  • Hello,

    You are correct. The application ID is intended for exactly this. If you have several types of nodes in your network, you can differentiate them using the application ID. Note that all the nodes in your network will still retransmit the DFU packets (like it would with any other Mesh packet), in case there are some other nodes that are not in range of the original publisher that needs this update. 

    Just be aware that when you are testing the DFU from the getting started guide, and you have more nodes, you may notice that these nodes are not actually in a network. They are not provisioned at any point. The DFU runs outside the encryption of the network, but your nodes will only accept packets that are using the same keyset and manufacturer ID as your nodes use in your device page.

    Best regards,

    Edvin

  • If you have several types of nodes in your network, you can differentiate them using the application ID

    So, If I were to have only one node as the gateway to push all the DFU updates into the mesh, I need to have a different device page on the gateway node every time I push a different firmware?

    in other words, does the gateway node check the application id after the update is successfully loaded onto mesh or initially when we try to push the update?

    Because the device page that is flashed on the gateway node might have a different application id and that varies with every new firmware that is being updated.

  • Just be aware that when you are testing the DFU from the getting started guide, and you have more nodes, you may notice that these nodes are not actually in a network. They are not provisioned at any point. The DFU runs outside the encryption of the network

    Just to make sure, the nodes need not be connected in a mesh network? 

    Yesterday when I tried to push the DFU on the Enocean switch example to which I added the DFU functionality, it was pushing to only one device but not both. I thought that provisioning was required. If they need not be provisioned then, I need to try the process again and see the result!!

  • No. They do not need to be provisioned, but note that it takes some time even after the nrfutil cmd window says 100% until the update is finished. I believe it is done transmitting, but leave it on for a couple of minutes more. Then you will see that both devices (if they are configured with the same device_page (application version, application ID and manufacturer ID) will update the firmware. It is easy to confirm this with blinky, because it is easy to see when it is done (when it starts to blink). 

    Can you test this? I have seen several posts claiming that it doesn't work because they restart the process when it reaches 100%. Just try to leave it on for a couple of minutes more.

    BR,

    Edvin

Reply
  • No. They do not need to be provisioned, but note that it takes some time even after the nrfutil cmd window says 100% until the update is finished. I believe it is done transmitting, but leave it on for a couple of minutes more. Then you will see that both devices (if they are configured with the same device_page (application version, application ID and manufacturer ID) will update the firmware. It is easy to confirm this with blinky, because it is easy to see when it is done (when it starts to blink). 

    Can you test this? I have seen several posts claiming that it doesn't work because they restart the process when it reaches 100%. Just try to leave it on for a couple of minutes more.

    BR,

    Edvin

Children
  • Can you test this? I have seen several posts claiming that it doesn't work because they restart the process when it reaches 100%. Just try to leave it on for a couple of minutes more.

    I tried it now but I couldn't reproduce the situation. I was transferring the DFU to both the board as LED1 and LED3 were ON while the transfer was taking place and it did push the update successfully resulting in LED2 blinking.

    Then you will see that both devices (if they are configured with the same device_page (application version, application ID and manufacturer ID) will update the firmware.

    If I were to have only one node as the gateway to push all the DFU updates into the mesh with various application ID's, do I need to have a different device page on the gateway node every time I push a different firmware?

    Because the device page that is flashed on the gateway node might have a different application id and that varies with every new firmware that is being updated.

    The new documentation released today states that the node checks for the application ID first and then decides whether to relay it or ignore. How can we make sure whether the node is going to relay or ignore?

    Does the device page contain application id, application version details or it just contains device series and soft device information?

  • I believe that the enocean FW is a bit different than other examples. Can you try with one of the others, if you do not intend to use enocean in the end?

    The Enocean switches are energy harvesting devices. I don't think they are listening at all times, as other mesh nodes. They only wake up and send a message when a button is pushed. This is probably why you don't see that they get the DFU packets over Mesh.

    Best regards,

    Edvin

  • Can you try with one of the others, if you do not intend to use enocean in the end?

    I did add the DFU example to the experimental_dimming example and it works fine.

    Can I have an explanation about pushing the DFU to a gateway node and device page that I asked in my previous comment on this thread?

    Thank you.

  • Oh, sorry.

    Yes. You can push a FW with another application ID through a node.

    E.g. A network with 3 nodes, one with application ID 1, one with application ID 2, and one with application ID 3. Only the node with application ID 1 is connected via serial, and does all the pushing of the data.

    Generate 3 DFU images. Each with their own application ID, (1, 2 and 3):

    nrfutil dfu genpkg --application ..\..\bin\blinky\blinky_nrf52832_xxAA_s132_6.1.0.hex --company-id 0x00000059 --application-id 1 --application-version 2 --key-file data\private_key.txt --sd-req 0x00AF --mesh data\dfu_test1.zip
    nrfutil dfu genpkg --application ..\..\bin\blinky\blinky_nrf52832_xxAA_s132_6.1.0.hex --company-id 0x00000059 --application-id 2 --application-version 2 --key-file data\private_key.txt --sd-req 0x00AF --mesh data\dfu_test2.zip
    nrfutil dfu genpkg --application ..\..\bin\blinky\blinky_nrf52832_xxAA_s132_6.1.0.hex --company-id 0x00000059 --application-id 3 --application-version 2 --key-file data\private_key.txt --sd-req 0x00AF --mesh data\dfu_test3.zip

    Now, to test this, I used the dfu example, and the blinky example as the DFU image, as you can see above. To speed things up a bit, I changed one thing in the DFU example. in nrf_mesh_dfu.c, line 75, I changed:

    #define TIMER_DATA_TIMEOUT_US               (600000000)  /**< Time to wait for next data during a transfer. */
    to
    #define TIMER_DATA_TIMEOUT_US               (10000000)   /**< Time to wait for next data during a transfer. */
    
    Resulting in a 10 second timeout instead of 10 minutes.
    
    

    This is just because the devices that the packet isn't intended for doesn't by default discover when the DFU transfer is complete, but stays in DFU mode for another 10 minutes.

    Reducing this to 10 seconds, I then used the bat script:

    REM nrfutil keys --gen-key data\private_key.txt
    nrfutil keys --show-vk hex data\private_key.txt
    
    nrfutil dfu genpkg --application ..\..\bin\blinky\blinky_nrf52832_xxAA_s132_6.1.0.hex --company-id 0x00000059 --application-id 1 --application-version 2 --key-file data\private_key.txt --sd-req 0x00AF --mesh data\dfu_test1.zip
    nrfutil dfu genpkg --application ..\..\bin\blinky\blinky_nrf52832_xxAA_s132_6.1.0.hex --company-id 0x00000059 --application-id 2 --application-version 2 --key-file data\private_key.txt --sd-req 0x00AF --mesh data\dfu_test2.zip
    nrfutil dfu genpkg --application ..\..\bin\blinky\blinky_nrf52832_xxAA_s132_6.1.0.hex --company-id 0x00000059 --application-id 3 --application-version 2 --key-file data\private_key.txt --sd-req 0x00AF --mesh data\dfu_test3.zip
    
    cd tools\dfu
    REM python device_page_generator.py -d nrf52832_xxAA -sd "s132_6.1.0"
    cd ..\..
    
    nrfjprog -e --snr 111111111
    nrfjprog -e --snr 222222222
    nrfjprog -e --snr 333333333
    
    nrfjprog --program ..\..\bin\softdevice\s132_nrf52_6.1.0_softdevice.hex --verify --snr 111111111
    nrfjprog --program ..\..\bin\softdevice\s132_nrf52_6.1.0_softdevice.hex --verify --snr 222222222
    nrfjprog --program ..\..\bin\softdevice\s132_nrf52_6.1.0_softdevice.hex --verify --snr 333333333
    
    nrfjprog --program ..\..\bin\bootloader\gccarmemb\mesh_bootloader_gccarmemb_nrf52832_xxAA.hex --verify --snr 111111111
    nrfjprog --program ..\..\bin\bootloader\gccarmemb\mesh_bootloader_gccarmemb_nrf52832_xxAA.hex --verify --snr 222222222
    nrfjprog --program ..\..\bin\bootloader\gccarmemb\mesh_bootloader_gccarmemb_nrf52832_xxAA.hex --verify --snr 333333333
    
    nrfjprog --program build\dfu_nrf52832_xxAA_s132_6.1.0_Debug\dfu_nrf52832_xxAA_s132_6.1.0.hex --verify --snr 111111111
    nrfjprog --program build\dfu_nrf52832_xxAA_s132_6.1.0_Debug\dfu_nrf52832_xxAA_s132_6.1.0.hex --verify --snr 222222222
    nrfjprog --program build\dfu_nrf52832_xxAA_s132_6.1.0_Debug\dfu_nrf52832_xxAA_s132_6.1.0.hex --verify --snr 333333333
    
    nrfjprog --program tools\dfu\bin\device_page_id_1.hex --verify --snr 111111111
    nrfjprog --program tools\dfu\bin\device_page_id_2.hex --verify --snr 222222222
    nrfjprog --program tools\dfu\bin\device_page_id_3.hex --verify --snr 333333333
    
    nrfjprog --reset --snr 111111111
    nrfjprog --reset --snr 222222222
    nrfjprog --reset --snr 333333333
    
    TIMEOUT 10
    
    nrfutil --verbose dfu serial -pkg data\dfu_test2.zip -p COM7 -b 115200 -fc --mesh
    
    TIMEOUT 15
    
    nrfutil --verbose dfu serial -pkg data\dfu_test3.zip -p COM7 -b 115200 -fc --mesh
    
    TIMEOUT 15
    
    nrfutil --verbose dfu serial -pkg data\dfu_test1.zip -p COM7 -b 115200 -fc --mesh

    As you can see, it waits 15 seconds between each transfer, allowing the nodes to go back to default mode (not DFU mode), so that it is ready to receive a new packet.

    As you also can see, I transfer the image with application ID 2, 3 and then 1. All is sent through the COM port belonging to the device with application ID 1.

    When it is done, all 3 devices is updated. Now it uses the same application, but with different application IDs. The same method can be used to update with different applications to the devices with different application IDs.

    Best regards,

    Edvin

  • Thanks for a detailed reply.

    Next question would be, Does the keys affect the DFU? 

    To elaborate my question, does the device page generation has dependency on the keys(private, public)? 

    If yes, can I have a device page generated with a set of keys and successfully perform firmware update with the DFU.zip created with a different set of keys? 

    Thank you.

Related