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
  • Sure, I'll edit the question and add the code for that, but I've stepped through the SDK sources using debug LEDs and found that there are two problems. The first is that the byte order for the DFU control point value was wrong. I was sending 0x0104 but needed to send 0x0401. The second is that the bond sharing is failing. The call to dfu_ble_svc_set_peer_data() at dfu_app_handler.c L99, which is an SVC, fails. I don't yet have any idea why that fails.

Reply
  • Sure, I'll edit the question and add the code for that, but I've stepped through the SDK sources using debug LEDs and found that there are two problems. The first is that the byte order for the DFU control point value was wrong. I was sending 0x0104 but needed to send 0x0401. The second is that the bond sharing is failing. The call to dfu_ble_svc_set_peer_data() at dfu_app_handler.c L99, which is an SVC, fails. I don't yet have any idea why that fails.

Children
No Data
Related