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

DFU control point write, app not restarting into bootloader, gcc, SDK 8.0.0

I've followed the instructions for adding the DFU service to my app to the letter and can see the DFU service from the central and can enable notifications on the control point and write a 01 04 to it to kick off DFU OTA for the application. The application does NOT restart into the bootloader, however. I have some debug LEDs on my board that tell me so.

I'm using SDK 8.0.0 on the whole but for GCC, the bootloader_util_gcc.c StartApplication() assembler appears to broken in 8.0.0, from what I read here, so I've pulled that source into my project and used the implementation from SDK 8.1.1.

On a normal reset I can see my bootloader running properly and starting the application. I'm writing to the control point characteristic both from an Android app and from the MCP on Windows. Neither works. I can't connect to the device using the MCP on Android (no CONNECT button on the UI next to the device).

Here's the code for the Android app (central), anyway. There is no error on writing the characteristic value.

    // nordicDfuControlPoint is the characteristic, from discovery.
    final BluetoothGattDescriptor descriptor =
            nordicDfuControlPoint.getDescriptor(BleCharacteristic.CCCD);

    if (descriptor == null) {
        Log.e(TAG, "Can't write descriptor for Nordic DFU control point." +
                " BluetoothGattCharacteristic.getDescriptor() returned null.");
        return;
    }

    Log.d(TAG, "Enabling notifications on characteristic for Nordic DFU control point.");

    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); // {0x01, 0x00}

    if (!gatt.writeDescriptor(descriptor)) {
        Log.e(TAG, "Can't write descriptor for Nordic DFU control point for enable."
                + " BluetoothGatt.writeDescriptor() returned false.");

        // See BluetoothGatt.java L1020. If either of these are null, we get false back.
        Log.e(TAG, "descriptor.getCharacteristic(): " + descriptor.getCharacteristic());
        Log.e(TAG, "characteristic.getService(): "
                + descriptor.getCharacteristic().getService());
    }

    new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
        @Override
        public void run() {
            nordicDfuControlPoint.setValue(NORDIC_DFU_UPDATE_APPLICATION, // Integer, 0x0104.
                    BluetoothGattCharacteristic.FORMAT_UINT32, 0);

            if (!gatt.writeCharacteristic(nordicDfuControlPoint)) {
                Log.e(TAG, "Can't write value for Nordic DFU control point for update application."
                        + " BluetoothGatt.writeDescriptor() returned false.");

                // See BluetoothGatt.java L1020. If either of these are null, we get false back.
                Log.e(TAG, "descriptor.getCharacteristic(): " + descriptor.getCharacteristic());
                Log.e(TAG, "characteristic.getService(): "
                        + descriptor.getCharacteristic().getService());
            }
        }
    }, 2000); // 2s

My bootloader code has been modified from the example to remove the button stuff and turn some of my LEDs on, not much else.

How do I debug this?

[EDIT]

StartApplication() implementation: bootloader_util_gcc_bike.c

[EDIT]

Before dfu_app_handler.c calls dfu_ble_svc_set_peer_data(), the key_set passed in looks like this to gdb:

		{
		  keys_periph = {enc_key = {p_enc_key = 0x20003d88}, p_id_key = 0x20002a80 <m_local_id_info>, p_sign_key = 0x0},
		  keys_central = {enc_key = {p_enc_key = 0x0}, p_id_key = 0x200029f0 <m_peer_table>, p_sign_key = 0x0}
		}

I can't see any more detail than that in gdb.

Parents
  • @Eliot: Could you explain the issue you have with flashing the example ? I don't really get it if you can flash your own hex but not the hex from our example.

    Could you let me know which bootloader you are using (SDK version) ? Have you tried the SDK v8.1 bootloader ? As suggested by Vidar, there are some modification added to dfu_ble_svc.c file to support gcc.

    You were correct on the app_context_load(), we forgot to mention it in the documentation, we will try to add that. The main purpose is to tell the application to send the service changed notification after it finishes with DFU. But you still should be able to jump to DFU bootloader, with or without that call.

    I attached in the answer the 2 hexes, SDK v8.1 bootloader and hrs_dfu application I compiled using gcc (v4.9 2015q1) on Window. I tested and it worked fine.

    nrf51422_xxac_s110.hex

    bootloader.hex

Reply
  • @Eliot: Could you explain the issue you have with flashing the example ? I don't really get it if you can flash your own hex but not the hex from our example.

    Could you let me know which bootloader you are using (SDK version) ? Have you tried the SDK v8.1 bootloader ? As suggested by Vidar, there are some modification added to dfu_ble_svc.c file to support gcc.

    You were correct on the app_context_load(), we forgot to mention it in the documentation, we will try to add that. The main purpose is to tell the application to send the service changed notification after it finishes with DFU. But you still should be able to jump to DFU bootloader, with or without that call.

    I attached in the answer the 2 hexes, SDK v8.1 bootloader and hrs_dfu application I compiled using gcc (v4.9 2015q1) on Window. I tested and it worked fine.

    nrf51422_xxac_s110.hex

    bootloader.hex

Children
Related