UART DFU of a nRF9160 in recovery mode via nRF5340.

Hello everyone, 

I guess my question is more conceptual rather than a specific issue with the code. 

I am working on a device featuring an nRF5340 chip and an nRF9160 chip which are linked by a UART interfface and 4 gpios. When it comes to DFU, i am able to update the firmware of the nRF5340 without issues. Although it could be possible to update the nRF9160 via LTE, the device might need to be updated in areas where there is no LTE connection available. For the update of the nRF9160 I would like to send the data to the nRF5340 via BLE which should transfer the new image to the nRF9160. While the nRF5340 has two slots in flash, the nRF9160 has only one slot and will be put in recovery mode for the DFU. 

To transmit the images over BLE, an ios app is going to be written. 

I have read the following posts, which tackle similar ideas : 

 nRF91 firmware upgrade over BLE  Here the image is sent via a PC running mcumgr commands and the nRF52 DK simply forwards it to the nRF9160. 

  Example For Using UART DFU on NRF52832 on both sides of communications  This post highlights the fact that mcuboot expects the image to be sent using the smp protocol. Or alternatively to modify the part of mcuboot especially the function boot_serial_input(). 

To preserve compatibility with upcoming versions of mcuboot I don't want to modify the sourcecode of mcuboot otherwise I am tied to that custom version or have to replicate my changes in every new version of mcuboot. 

I am considering basing the ios app on the device manager sample: 

https://github.com/NordicSemiconductor/IOS-nRF-Connect-Device-Manager 

I would like to clarify if it is possible to use the device manager on the ios app to send the nRF9160 image to the nRF5340 over BLE and having the nRF5340 simply forward the data chunks to the nRF9160, which is in recovery mode at that time. 

Hypothesis: 

I assume that, in order for this to work, the data chunks should be formatted using the SMP protocol with a serial transport layer, then each transport layer frame should be transmitted over BLE to a custom service which will simply forward the data as they are already formatted for serial transport. 

Since i am not too familiar with SMP and MCUmgr I am unsure if this is possible, could you confirm that idea? 

If this is a viable solution, are there any pitfalls to be aware of? How would you advise to proceed on the ios app? 

I am developping with the SDK version V2.7.0 and the Toolchain V2.7.0 

I am looking forward to reading your responses. 

Kind regards 

Colin 

  • Hi, I am back with some more insights and questions on the usage of the img_mgmt_client. The API usage seems to  be restricted to the test code. 

    The project I am working on is confidential so I can't share the whole code.  Here is a short snippet that shows how I use the img_mgmt_client API : 

    struct mcumgr_image_upload res_buf; 
    struct img_mgmt_client img_mgr_cli;
    struct smp_client_object smp_client;
    struct mcumgr_image_data img_data[1];
    
    #define READ_SIZE 124 
    
    //Initialize the smp_client and the img_mgmt_client
    smp_client_object_init(&smp_client, SMP_SERIAL_TRANSPORT);
    img_mgmt_client_init(&img_mgr_cli, &smp_client, 1, img_data);
    
    //Initialise the image upload
    err = img_mgmt_client_upload_init(&img_mgr_cli, image_size, 0, NULL);
    if(err != 0){
        LOG_ERR("Failed to initialise the image upload");
    }
    
    //Upload one chunk to the nRF9160
    err = img_mgmt_client_upload(&img_mgr_cli, image_data, READ_SIZE, &res_buf);
    

    The execution of 

    img_mgmt_client_upload() fails due to an Attribution unit violation, the call stack is as follows: 

     

    sys_dlist_remove(sys_dnode_t * node) (ncs\v2.7.0\zephyr\include\zephyr\sys\dlist.h:506) 
    
    sys_dlist_get(sys_dlist_t * list) (ncs\v2.7.0\zephyr\include\zephyr\sys\dlist.h:530) 
    
    handle_poll_events(uint32_t state, struct k_queue * queue) (ncs\v2.7.0\zephyr\kernel\queue.c:90) 
    
    queue_insert(struct k_queue * queue, void * prev, void * data, _Bool alloc, _Bool is_append) (ncs\v2.7.0\zephyr\kernel\queue.c:170) 
    
    net_buf_put(struct k_fifo * fifo, struct net_buf * buf) (ncs\v2.7.0\zephyr\subsys\net\buf.c:450) 
    
    smp_client_send_cmd(struct smp_client_object * smp_client, struct net_buf * nb, smp_client_res_fn cb, void * user_data, int timeout_in_sec) (ncs\v2.7.0\zephyr\subsys\mgmt\mcumgr\smp_client\src\client.c:322) 
    
    img_mgmt_client_upload(struct img_mgmt_client * client, const uint8_t * data, size_t length, struct mcumgr_image_upload * res_buf) (ncs\v2.7.0\zephyr\subsys\mgmt\mcumgr\grp\img_mgmt_client\src\img_mgmt_client.c:420) 
    
    perform_nrf9160_dfu(struct k_work * work) (Application Level Function, Top of callstack)

     

    It seems that the FIFO element in the SMP_client struct makes an illegal access. But I don't understand why, as I have initialized the SMP_client. 

    Right now I am still unsure if using the img_mgmt_client API directly from Application level code the correct way is or what I am missing. 

    Based on this update, do you have more inputs that could help me advance with the DFU implementation? 

    Thank you for the support 

    Cheers, Colin 

Related