nRF5340 BLE DFU from NET core

Hello! 
Introduction. Responsibilities of the cores in my device:
1. app core. 
1.1. data processing from a stereo microphone
1.2. data sending to net core.
2. net core. 
2.1. ble communication, services supporting. 
2.2. data receiving from app core.

Everything works fine :)
But now I want to add BLE DFU )

As I understood from examples, I should use app core for smp server, so I should use ble communication support on app core, which changes my whole architecture.

Could please anyone help me with that situation? :)

Parents
  • Hi,

    What you want to do is not the standard way to do stuff, so it is not supported or tested.

    However, it can be done.

    First, tell me: Do you want to update both cores?

    How large is your network core application?

    Regards,
    Sigurd Hellesvik

  • For both cores:

    [192/196] Linking CXX executable zephyr\cpuapp.elf
    Memory region    Used Size      Region Size   %age Used
    FLASH:               85552 B         1 MB              8.16%
    RAM:                  399824 B        448 KB          87.15%
    IDT_LIST:           0 GB               2 KB              0.00%

    [210/210] Linking C executable zephyr\cpunet.elf
    Memory region    Used Size       Region Size  %age Used
    FLASH:               254588 B        256 KB          97.12%
    RAM:                  56096 B           64 KB           85.60%
    SRAM1:              0 GB                64 KB           0.00%
    IDT_LIST:            0 GB               2 KB              0.00%

  •  thank you for your detailed answer! 
     1. Flash usage. 
    I checked memory distribution on the net core with sample 'peripheral_lbs' for nrf5340dk borad.

    CPUNET flash_primary (0x40000 - 256kB):
    +--------------------------------------------+
    +---0x1000000: b0n_container (0x8800 - 34kB)-+
    | 0x1000000: b0n (0x8580 - 33kB) |
    | 0x1008580: provision (0x280 - 640B) |
    +---0x1008800: app (0x37800 - 222kB)---------+
    | 0x1008800: hci_rpmsg (0x37800 - 222kB) |
    +--------------------------------------------+

    CPUNET sram_primary (0x10000 - 64kB):
    +-------------------------------------------+
    | 0x21000000: sram_primary (0x10000 - 64kB) |
    +-------------------------------------------+

      So yes, I should reduce flash usage on the net core to be able to use  b0n bootloader.

     
    2. Alternative 1
    Could you please explane how to add FOTA handler to the network core or where I can find the example?

  • valeriy_simakov said:
    Could you please explane how to add FOTA handler to the network core or where I can find the example?

    Well we dont have any example as such. For the application core we use the mcumgr library for this, but this will just write to flash directly. For Alt1, you would want to transfer the DFU image received to the application core. I think this can be done in one of three ways:

    A: Trick/patch the mcumgr library to make it send data to the application core instead of writing to flash.

    B: Write a BLE service that uses the SMP Protocol to receive the DFU and send it to the application core.

    C: Write a custom BLE service that receives a custom binary with your DFU files and send it to the application core

  •  
    * Thanks, I will investigate all three ways. 

    * Net core flash usage is so big. I reduced it by logging disabling. Could you please tell me how to reduce it more efficiently? I attached the file from 'rom_report'. The section 'no paths' takes 50% :(
    net_core_flash_usage.txt

    * To be honest, I had doubts about my architecture. The app core continuously accumulates data from the microphone for a certain time and transmits it in chunks to the network core, which then sends the data via BLE. I did this to unload the app core so that it would not send data over BLE. Maybe I use the wrong way and there would be no problems with continuously receiving and sending data. I need your opinion.

  • static struct bt_gatt_attr smp_bt_attrs[] = {
        /* SMP Primary Service Declaration */
        BT_GATT_PRIMARY_SERVICE(&smp_bt_svc_uuid),

        BT_GATT_CHARACTERISTIC(&smp_bt_chr_uuid.uuid,
                       BT_GATT_CHRC_WRITE_WITHOUT_RESP |
                       BT_GATT_CHRC_NOTIFY,
    #ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN
                       BT_GATT_PERM_WRITE_AUTHEN,
    #else
                       BT_GATT_PERM_WRITE,
    #endif
                       NULL, smp_bt_chr_write, NULL),
        BT_GATT_CCC(smp_bt_ccc_changed,
    #ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN
                       BT_GATT_PERM_READ_AUTHEN |
                       BT_GATT_PERM_WRITE_AUTHEN),
    #else
                       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
    #endif
    };

    With corresponding CONFIG_x values in 'peripheral_lbs' example we have attributes without response where mcumgr writes the data. 
    I think I can write BLE service wrapper of smp service to get data and send it to app core (data, len). On app core I can write smp_uart wrapper to receive data. What do you think about it?
  • valeriy_simakov said:
    static struct bt_gatt_attr smp_bt_attrs[] = {
        /* SMP Primary Service Declaration */
        BT_GATT_PRIMARY_SERVICE(&smp_bt_svc_uuid),

        BT_GATT_CHARACTERISTIC(&smp_bt_chr_uuid.uuid,
                       BT_GATT_CHRC_WRITE_WITHOUT_RESP |
                       BT_GATT_CHRC_NOTIFY,
    #ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN
                       BT_GATT_PERM_WRITE_AUTHEN,
    #else
                       BT_GATT_PERM_WRITE,
    #endif
                       NULL, smp_bt_chr_write, NULL),
        BT_GATT_CCC(smp_bt_ccc_changed,
    #ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN
                       BT_GATT_PERM_READ_AUTHEN |
                       BT_GATT_PERM_WRITE_AUTHEN),
    #else
                       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
    #endif
    };

    Im not a BLE expert, but I can suggest that if you want to verify this, check our DFU SMP service ( and .c file), as this is the closest we got to that.

    But yes, this implementing of your own service for SMP.

    valeriy_simakov said:
    I think I can write BLE service wrapper of smp service to get data and send it to app core (data, len).

    Nice!

    valeriy_simakov said:
    On app core I can write smp_uart wrapper to receive data. What do you think about it?

    I would suggest that you use DFU Target on the application core to receive the data. This is the library we have for custom handling of received DFU binaries.

Reply
  • valeriy_simakov said:
    static struct bt_gatt_attr smp_bt_attrs[] = {
        /* SMP Primary Service Declaration */
        BT_GATT_PRIMARY_SERVICE(&smp_bt_svc_uuid),

        BT_GATT_CHARACTERISTIC(&smp_bt_chr_uuid.uuid,
                       BT_GATT_CHRC_WRITE_WITHOUT_RESP |
                       BT_GATT_CHRC_NOTIFY,
    #ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN
                       BT_GATT_PERM_WRITE_AUTHEN,
    #else
                       BT_GATT_PERM_WRITE,
    #endif
                       NULL, smp_bt_chr_write, NULL),
        BT_GATT_CCC(smp_bt_ccc_changed,
    #ifdef CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN
                       BT_GATT_PERM_READ_AUTHEN |
                       BT_GATT_PERM_WRITE_AUTHEN),
    #else
                       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
    #endif
    };

    Im not a BLE expert, but I can suggest that if you want to verify this, check our DFU SMP service ( and .c file), as this is the closest we got to that.

    But yes, this implementing of your own service for SMP.

    valeriy_simakov said:
    I think I can write BLE service wrapper of smp service to get data and send it to app core (data, len).

    Nice!

    valeriy_simakov said:
    On app core I can write smp_uart wrapper to receive data. What do you think about it?

    I would suggest that you use DFU Target on the application core to receive the data. This is the library we have for custom handling of received DFU binaries.

Children
  • Hi  
    Well, I'm stuck on the "wrapper of smp service" on the app core side. I couldn't find an example of DFU Target usage in my sdk. 
    Now I'm trying to use the "common way". I'm worried about BLE speed, because now I use BLE stack on the app core. But as I understand physically, net core will send the final data, am I right?

  • I mean, does the app core use the ble api via rpmsg in net core ? Аnd all the ble stack is contained in the network core.

  • Bad news. I can't get the same speed of data transfer. 

    00> [00:01:19.984,344] <inf> app: do_pdm_transfer: PCM output rate: 16000, channels: 2
    00> [00:01:19.984,375] <inf> app: sender_clear: Cleanup sender, before:
    00> [00:01:19.984,375] <inf> app: sender_clear: Cashed slab num free 60
    00> [00:01:19.984,405] <inf> app: sender_clear: Sender slab num free 10
    00> [00:01:19.984,436] <inf> app: sender_clear: Cleanup sender, after:
    00> [00:01:19.984,436] <inf> app: sender_clear: Cashed slab num free 60
    00> [00:01:19.984,466] <inf> app: sender_clear: Sender slab num free 10
    00> [00:01:19.984,497] <inf> app: do_pdm_transfer: Expected amount of data, bytes: 576000
    00> [00:01:20.085,662] <inf> cpu_net: slab_notify: New packet, number: 1, payload size: 487, packet size: 495
    00> --- 13 messages dropped ---
    00> [00:01:20.085,784] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 974
    00> [00:01:20.085,876] <inf> cpu_net: slab_notify: New packet, number: 2, payload size: 487, packet size: 495
    00> [00:01:20.085,998] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 1461
    00> [00:01:20.086,090] <inf> cpu_net: slab_notify: New packet, number: 3, payload size: 487, packet size: 495
    00> [00:01:20.086,212] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 1948
    00> [00:01:20.086,303] <inf> cpu_net: slab_notify: New packet, number: 4, payload size: 487, packet size: 495
    00> [00:01:20.086,425] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 2435
    00> [00:01:20.086,517] <inf> cpu_net: slab_notify: New packet, number: 5, payload size: 487, packet size: 495
    00> [00:01:20.086,639] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 2922
    00> [00:01:20.086,730] <inf> cpu_net: slab_notify: New packet, number: 6, payload size: 487, packet size: 495
    00> [00:01:20.086,853] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 3409
    00> [00:01:20.086,944] <inf> cpu_net: slab_notify: New packet, number: 7, payload size: 487, packet size: 495
    00> [00:01:20.087,066] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 3896
    00> [00:01:20.087,158] <inf> cpu_net: slab_notify: New packet, number: 8, payload size: 487, packet size: 495
    00> [00:01:20.087,310] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 4383
    00> [00:01:20.087,402] <inf> cpu_net: slab_notify: New packet, number: 9, payload size: 487, packet size: 495
    00> [00:01:20.087,524] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 4870
    00> [00:01:20.087,646] <inf> cpu_net: slab_notify: New packet, number: 10, payload size: 487, packet size: 495
    00> [00:01:20.087,768] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 5357
    00> [00:01:20.087,860] <inf> cpu_net: slab_notify: New packet, number: 11, payload size: 487, packet size: 495
    00> [00:01:20.087,982] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 5844
    00> [00:01:20.088,104] <inf> cpu_net: slab_notify: New packet, number: 12, payload size: 487, packet size: 495
    00> [00:01:20.088,226] <inf> cpu_net: slab_notify: Payload size to send: 69, sent: 6331
    00> [00:01:20.088,256] <inf> cpu_net: slab_notify: New packet, number: 13, payload size: 69, packet size: 77
    00> [00:01:20.188,415] <inf> cpu_net: slab_notify: New slab: 0x2007e100
    00> [00:01:20.188,446] <inf> cpu_net: slab_notify: New slab index: 1
    00> [00:01:20.188,476] <inf> cpu_net: slab_notify: Current MTU: 498
    00> [00:01:20.188,476] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 0
    00> [00:01:20.188,568] <inf> cpu_net: slab_notify: New packet, number: 14, payload size: 487, packet size: 495
    00> [00:01:20.188,690] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 487
    00> [00:01:20.188,812] <inf> cpu_net: slab_notify: New packet, number: 15, payload size: 487, packet size: 495
    00> [00:01:20.188,903] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 974
    00> [00:01:20.189,025] <inf> cpu_net: slab_notify: New packet, number: 16, payload size: 487, packet size: 495
    00> [00:01:20.189,147] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 1461
    00> [00:01:20.189,239] <inf> cpu_net: slab_notify: New packet, number: 17, payload size: 487, packet size: 495
    00> [00:01:20.189,361] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 1948
    00> [00:01:20.189,453] <inf> cpu_net: slab_notify: New packet, number: 18, payload size: 487, packet size: 495
    00> [00:01:20.189,575] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 2435
    00> [00:01:20.189,666] <inf> cpu_net: slab_notify: New packet, number: 19, payload size: 487, packet size: 495
    00> [00:01:20.189,788] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 2922
    00> [00:01:20.189,880] <inf> cpu_net: slab_notify: New packet, number: 20, payload size: 487, packet size: 495
    00> [00:01:20.673,980] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 3409
    00> [00:01:20.674,102] <inf> cpu_net: slab_notify: New packet, number: 21, payload size: 487, packet size: 495
    00> [00:01:21.274,810] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 3896
    00> [00:01:21.274,902] <inf> cpu_net: slab_notify: New packet, number: 22, payload size: 487, packet size: 495
    00> [00:01:21.873,962] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 4383
    00> [00:01:21.874,084] <inf> cpu_net: slab_notify: New packet, number: 23, payload size: 487, packet size: 495
    00> [00:01:22.474,822] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 4870
    00> [00:01:22.474,914] <inf> cpu_net: slab_notify: New packet, number: 24, payload size: 487, packet size: 495
    00> [00:01:23.133,972] <inf> cpu_net: slab_notify: Payload size to send: 495, sent: 5357
    00> [00:01:23.134,063] <inf> cpu_net: slab_notify: New packet, number: 25, payload size: 487, packet size: 495
    00> [00:01:23.674,591] <inf> settings_service: WriteRecEnableFlag: New value of record enable flag 0
    00> [00:01:23.674,621] <inf> cpu_net: signal_settings_notify: Send settings to App
    00> [00:01:23.674,621] <inf> cpu_net: signal_settings_notify: Record duration, sec: 9
    00> [00:01:23.674,652] <inf> cpu_net: signal_settings_notify: Record enable flag, value: 0


    1 slab = 6400B.
    The first slab is sent quickly, then the speed starts to drop.

    I use bt_gatt_notify() api. 
    How can I improve my performance?

  • There is a little while since last time I looked at this ticket. One thing is unclear to me now when I look over it again, so could you referesh my memory:

    Do you use RPC for this?

  • In my initial architecture, I use:

    1. mbox_channel

    2. shared memory
    3. my binary for net core with BLE processing and main logic on app core. 

    But I'm stuck with OTA implementation. 

    Now I use "common way" architecture and write code in app core. 
    And use BLE API in app core, like bt_gatt_notify e.t.c. 

Related