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

DFU OTA nrftoolbox does not automatically reconnect when initiating dfu from application

Hi,

I am developing some DFU OTA firmware for nRF51822, QFAAH0 (v3 silicon, 256kB ROM, 16kB flash), on a custom board, using SD110v8. Both my application and bootloader were adapted from the Keil pack examples.

I am experiencing a funny behaviour using the android nrftoolbox app to perform dfu. The dfu is initiated from the application (not the bootloader).

I believe, the standard procedure is as follows, nrftoolbox tells the device to restart and enter bootloader mode, the device will restart in bootloader and re-advertise itself. nrftoolbox will reconnect to the device which is now in bootloader to continue the update.

My problem is, when I have my own bootloader and application programmed, after I press the UPLOAD button in nrftoolbox, the device will restart itself (enters bootloader mode). However the app does not reconnect to the device, instead it gets stuck in "Connecting..." and eventually timeout. Since now the device is in bootloader, I can press the UPLOAD button again and the dfu will continue without any further issues.

After a bit of debugging, I also discovered that, if I use the sample bootloader + my own application, the dfu process has no issues.

At first glance, this may be an issue in my own bootloader, however, after commenting out almost all of my modifications to the bootloader (so it is pretty much identical to the sample bootloader), nrftoolbox still cannot reconnect once the device is in bootloader mode. Additionally, I can still perform dfu using my bootloader, so the bootloader is PROBABLY working fine. The only problem is nrftoolbox does not reconnect to it, if i initiated dfu from the application.

My question is, how does nrftoolbox handle reconnection to the device when the dfu process is initiated from the application. I suspect that with my own bootloader + application, nrftoolbox cant identify the correct device to reconnect to and continue with the dfu.

Thanks in advance, Mike

  • Hi Hung, I think I finally fully understand what you mentioned earlier, regarding the address +1 issue. I did a bit of debugging and found that the MAC address agrees exactly for each of the 5 steps you talked about, if im using the default codes. In particular, in step 4, the advertising name is actually n/a and the MAC address is A (not A+1).

    So this means, in my own bootloader, somehow the reset didnt work as expected. Would you have any suggestion in where to look for potential causes for the A+1 issue in Step 4? I'm certain that the NoInit button is ticked for the last 0x80 bytes of RAM. And my RAM layout is as follows:

    • IRAM1 0x20002000 0x1F80
    • IRAM2 0x20003F80 0x0080 NoInit

    Also, FYI, the reason why I did my own DFU bootloader is I wanted to have both BLE and Serial, hence I have separated out many .c and .h files from the PACK, these are:

    • bootloader.c
    • bootloader_settings_arm.c
    • bootloader_util_arm.c
    • dfu_dual_bank.c
    • dfu_init_template.c
    • dfu_transport_ble.c
    • dfu_transport_serial.c
    • hci_mem_pool.c
    • hci_slip.c
    • hci_transport.c

    All other required source files are from the Keil PACKS.

    Thanks a lot for your time again. Mike.

  • @Mike: You can follow this instruction to set bootloader in debug mode.

    When running in debug mode, you can add a break point at dfu_transport_update_start() in bootloader.c to see what will be executed when you jump from application to bootloader. Most likely the dfu_ble_get_peer_data() has returned fail. Then you can check if the peer_data is set properly in your application by adding breakpoint at dfu_app_peer_data_set() in application and dfu_ble_set_peer_data() in bootloader

    You should also check if dfu_ble_svc.c file's option has been set with Memory Assignment to Zero Initialized Data (IRAM2).

    I would suggest you to use the no pack SDK's zip version instead of basing on the pack. It's easier to modify without using pack.

  • Hi Hung, I have followed your instructions to debug. Indeed, the dfu_ble_get_peer_data() fails. I also looked at the RAW Memory data. For the default bootloader, I see the memory at address 0x3F80 onwards changes when the device restarts from the application. Whereas for my own bootloader, the data at 0x3F80 onwards stays the same (doesnt change at all). This suggests that when using my own bootloader, the peer data is not written to the RAM.

    However, my question is, I am using the same application for both cases, why would it only work with one particular bootloader?

    Another question I have is, how does the application decide where to put the peer data? As the NoInit RAM section is not set up for the application. So how does the application know that starting from 0x3F80 is the NoInit area?

    Thanks a lot. Mike

    EDIT: I did a big of debugging on the application side. In particular, where the dfu_app_peer_data_set() is called. I noticed that the value in RAM doesnt get changed at all when this function is called. I added a bit of direct memory manipulation code with pointers, these code however changes the data in the RAM no problem. Please see the code below:

            err_code = dfu_ble_svc_set_peer_data(&m_peer_data); 
                                     // the previous line didnt change anything in the RAM at 0x20003F80
            APP_ERROR_CHECK(err_code);
    		
    		uint8_t *ptr;
    		ptr = (uint8_t*)0x20003F80;
    		for (int i=0; i<6; i++) {
    			*ptr = (uint8_t) m_peer_data.addr.addr[i];
    			ptr++;				
    		}
                                     // after the above line, the data in the RAM is changed accordingly
    
  • @Mike: sorry for that late response, I was on vacation.

    "how does the application decide where to put the peer data?": The application doesn't do the work to put data to the No-int area, it's the SVC call dfu_ble_svc_set_peer_data() that will jump to dfu_ble_set_peer_data in the bootloader code. In side that dfu_ble_set_peer_data() it will copy the data from source (m_peer_data from application) to destination (no-init area).

    I'm not sure why the SVC call didn't work or it couldn't modify the No-init RAM area. If possible please send me your bootloader project file, I can try to reproduce the issue here.

  • Hi Hung, I have created a case on mypage. The project is setup for my custom board, but it should load just fine on the new pca10028 dev board too.

Related