Subject: MPSL ASSERT: 69, 108 and HardFault when using ESB (CONFIG_ESB_MPSL_TIMESLOT) with BLE dual connection and ZMS on NCS v3.3.0 / nRF54L10

Hi,

I'm running NCS v3.3.0 on a Nordic nRF54L10 (nRF54L Series, Cortex-M33) with:
- BLE peripheral role, max 2 connections (dual connected simultaneously)
- ESB in CONFIG_ESB_MPSL_TIMESLOT mode
- ZMS library for non-volatile storage
- ESB PTX/PRX role switching every ~4 ms
(check if TX data pending → enter PTX → after TX done/callback → switch back to PRX)

Under combined BLE traffic (2 connections) + ESB communication, the device randomly crashes:

<err> mpsl_init: MPSL ASSERT: 69, 108
<err> os: ***** HARD FAULT *****
<err> os: Fault escalation (see below)
<err> os: ARCH_EXCEPT with reason 3
>>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
Current thread: 0x20007010 (idle)
Halting system

Key configuration:

# BLE
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_MAX_CONN=2
CONFIG_BT_DEVICE_NAME="RD-QED2"
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_CTLR_SDC_MAX_CONN_EVENT_LEN_DEFAULT=5000
CONFIG_BT_RADIO_NOTIFICATION_CONN_CB=y

# MPSL / ESB
CONFIG_MPSL=y
CONFIG_ESB_MPSL_TIMESLOT=y
CONFIG_MPSL_TIMESLOT_SESSION_COUNT=1
CONFIG_MPSL_WORK_STACK_SIZE=2048
CONFIG_ESB=y
CONFIG_ESB_CLOCK_INIT=y
CONFIG_ESB_TX_FIFO_SIZE=16
CONFIG_ESB_DYNAMIC_INTERRUPTS=y
CONFIG_ESB_RADIO_IRQ_PRIORITY=0
CONFIG_ESB_EVENT_IRQ_PRIORITY=1
CONFIG_NRFX_GPPI=y
CONFIG_DYNAMIC_INTERRUPTS=y
CONFIG_DYNAMIC_DIRECT_INTERRUPTS=y
CONFIG_MPSL_ASSERT_HANDLER=n

# ZMS
CONFIG_ZMS=y
CONFIG_PM_PARTITION_SIZE_ZMS_STORAGE=0x4000

My questions:
1. What does "MPSL ASSERT: 69, 108" mean in MPSL timeslot context? Is it an invalid timeslot request or incorrect return from the timeslot signal callback (e.g. p_next == NULL / bad extend action)?
2. Are there known issues/recommendations when toggling ESB PTX⇄PRX inside an MPSL timeslot while BLE (2 connections) is active on nRF54L Series?
3. Could BT_CTLR_SDC_MAX_CONN_EVENT_LEN_DEFAULT=5000 (5 ms) conflict with the 4 ms ESB role-check cycle and cause timeslot overruns / rejected requests?
4. What is the correct / safe sequence to stop ESB (PTX→PRX switch) and re-enter the MPSL timeslot to avoid this MPSL assertion?

Any clarification or reference would be greatly appreciated.

Thanks!

Parents
  • Hello,

    Can you try to set CONFIG_MPSL_HFCLK_LATENCY=1650 in the prj.conf file and try again to run the sample?

    Thanks.

    BR
    Kazi

  • Hi Nordic team,
    Regarding the first issue:
    It appears the root cause is related to the 32.768kHz clock offset on my board. Before applying the correction, stopping BLE advertising triggers an assert. This also happens during BLE and ESB coexistence — stopping either BLE or ESB at runtime results in the same assertion failure.
    Second question regarding NCS migration:
    When migrating from NCS 3.0.0 to NCS 3.3.0, I noticed that the compiled partitions.ymllayout has changed compared to the previous version. Using the default configuration, this difference causes issues when upgrading from older firmware versions.
    To maintain compatibility, I added a pm_static.ymlbased on the old partition layout, but compilation fails with the following error:
    -- Found partition manager static configuration : D:/00_work/03_multi_tx_rx_shift_optimize/f-e-wireless-shifting/pm_static_nrf54l15dk_nrf54l10_cpuapp.yml
    Partition 'mcuboot' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_pad' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_primary' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_primary_app' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_secondary' is not included in the dynamic resolving since it is statically defined.
    Partition 'zms_storage' is not included in the dynamic resolving since it is statically defined.
    Partition manager failed: Incorrect amount of gaps found in static configuration. There must be exactly one gap in the static configuration to support placing the dynamic partitions (such as 'app'). Gaps found (3):0x10800-0x85000 0xfa000-0xfb000 0xff000-0xfd000 The most common solution to this problem is to fill the smallest of these gaps with statically defined partition(s) until there is only one gap left. Alternatively re-order the already defined static partitions so that only one gap remains.
    Failed to partition region flash_primary, size of region: 1036288
    Partition Configuration:
    mcuboot:
      placement:
        align:
          end: 4096
        before:
        - mcuboot_primary
      size: 65536
    mcuboot_pad:
      placement:
        before:
        - mcuboot_primary_app
      size: 2048
    mcuboot_primary:
      size: 479232
    mcuboot_primary_app:
      size: 477184
    mcuboot_secondary:
      placement:
        after:
        - mcuboot_primary
        align:
          start: 4096
      size: 479232
    zms_storage:
      placement:
        align:
          start: 4096
        before:
        - end
      size: 16384
    Why did the default partition layout change after the migration? Is there a recommended way to keep using the original NCS 3.0.0 partition layout in NCS 3.3.0? Which configurations or files need to be updated?
    For reference, I will attach the partitions.ymlgenerated by NCS 3.0.0, the one generated by NCS 3.3.0, and my current pm_static.yml.
    Looking forward to your reply.
    Thanks!
    EMPTY_0:
      address: 0xf8000
      end_address: 0xf9000
      placement:
        after:
        - mcuboot_secondary
      region: flash_primary
      size: 0x1000
    app:
      address: 0x10800
      end_address: 0x84000
      region: flash_primary
      size: 0x73800
    bootconf:
      address: 0xffd080
      end_address: 0xffd084
      region: bootconf
      size: 0x4
    mcuboot:
      address: 0x0
      end_address: 0x10000
      placement:
        align:
          end: 0x1000
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0x10000
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10800
      placement:
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x800
    mcuboot_primary:
      address: 0x10000
      end_address: 0x84000
      orig_span: &id001
      - app
      - mcuboot_pad
      region: flash_primary
      sharers: 0x1
      size: 0x74000
      span: *id001
    mcuboot_primary_app:
      address: 0x10800
      end_address: 0x84000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x73800
      span: *id002
    mcuboot_secondary:
      address: 0x84000
      end_address: 0xf8000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x74000
    otp:
      address: 0xffd500
      end_address: 0xffd980
      region: otp
      size: 0x480
    sram_primary:
      address: 0x20000000
      end_address: 0x20030000
      region: sram_primary
      size: 0x30000
    zms_storage:
      address: 0xf9000
      end_address: 0xfd000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x4000
    
    EMPTY_0:
      address: 0xff000
      end_address: 0xff800
      placement:
        after:
        - zms_storage
      region: flash_primary
      size: 0x800
    EMPTY_1:
      address: 0xfa000
      end_address: 0xfb000
      placement:
        after:
        - mcuboot_secondary
      region: flash_primary
      size: 0x1000
    app:
      address: 0x10800
      end_address: 0x85000
      region: flash_primary
      size: 0x74800
    bootconf:
      address: 0xffd080
      end_address: 0xffd084
      region: bootconf
      size: 0x4
    mcuboot:
      address: 0x0
      end_address: 0x10000
      placement:
        align:
          end: 0x1000
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0x10000
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10800
      placement:
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x800
    mcuboot_primary:
      address: 0x10000
      end_address: 0x85000
      orig_span: &id001
      - mcuboot_pad
      - app
      region: flash_primary
      sharers: 0x1
      size: 0x75000
      span: *id001
    mcuboot_primary_app:
      address: 0x10800
      end_address: 0x85000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x74800
      span: *id002
    mcuboot_secondary:
      address: 0x85000
      end_address: 0xfa000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x75000
    sram_primary:
      address: 0x20000000
      end_address: 0x20030000
      region: sram_primary
      size: 0x30000
    zms_storage:
      address: 0xfb000
      end_address: 0xff000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x4000
    
    mcuboot:
      address: 0x0
      end_address: 0x10000
      placement:
        align:
          end: 0x1000
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0x10000
    
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10800
      placement:
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x800
    
    mcuboot_primary:
      address: 0x10000
      end_address: 0x85000
      orig_span: &id001
      - mcuboot_pad
      - app
      region: flash_primary
      sharers: 0x1
      size: 0x75000
      span: *id001
    
    mcuboot_primary_app:
      address: 0x10800
      end_address: 0x85000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x74800
      span: *id002
    
    mcuboot_secondary:
      address: 0x85000
      end_address: 0xfa000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x75000
    
    zms_storage:
      address: 0xfb000
      end_address: 0xff000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x4000
Reply
  • Hi Nordic team,
    Regarding the first issue:
    It appears the root cause is related to the 32.768kHz clock offset on my board. Before applying the correction, stopping BLE advertising triggers an assert. This also happens during BLE and ESB coexistence — stopping either BLE or ESB at runtime results in the same assertion failure.
    Second question regarding NCS migration:
    When migrating from NCS 3.0.0 to NCS 3.3.0, I noticed that the compiled partitions.ymllayout has changed compared to the previous version. Using the default configuration, this difference causes issues when upgrading from older firmware versions.
    To maintain compatibility, I added a pm_static.ymlbased on the old partition layout, but compilation fails with the following error:
    -- Found partition manager static configuration : D:/00_work/03_multi_tx_rx_shift_optimize/f-e-wireless-shifting/pm_static_nrf54l15dk_nrf54l10_cpuapp.yml
    Partition 'mcuboot' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_pad' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_primary' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_primary_app' is not included in the dynamic resolving since it is statically defined.
    Partition 'mcuboot_secondary' is not included in the dynamic resolving since it is statically defined.
    Partition 'zms_storage' is not included in the dynamic resolving since it is statically defined.
    Partition manager failed: Incorrect amount of gaps found in static configuration. There must be exactly one gap in the static configuration to support placing the dynamic partitions (such as 'app'). Gaps found (3):0x10800-0x85000 0xfa000-0xfb000 0xff000-0xfd000 The most common solution to this problem is to fill the smallest of these gaps with statically defined partition(s) until there is only one gap left. Alternatively re-order the already defined static partitions so that only one gap remains.
    Failed to partition region flash_primary, size of region: 1036288
    Partition Configuration:
    mcuboot:
      placement:
        align:
          end: 4096
        before:
        - mcuboot_primary
      size: 65536
    mcuboot_pad:
      placement:
        before:
        - mcuboot_primary_app
      size: 2048
    mcuboot_primary:
      size: 479232
    mcuboot_primary_app:
      size: 477184
    mcuboot_secondary:
      placement:
        after:
        - mcuboot_primary
        align:
          start: 4096
      size: 479232
    zms_storage:
      placement:
        align:
          start: 4096
        before:
        - end
      size: 16384
    Why did the default partition layout change after the migration? Is there a recommended way to keep using the original NCS 3.0.0 partition layout in NCS 3.3.0? Which configurations or files need to be updated?
    For reference, I will attach the partitions.ymlgenerated by NCS 3.0.0, the one generated by NCS 3.3.0, and my current pm_static.yml.
    Looking forward to your reply.
    Thanks!
    EMPTY_0:
      address: 0xf8000
      end_address: 0xf9000
      placement:
        after:
        - mcuboot_secondary
      region: flash_primary
      size: 0x1000
    app:
      address: 0x10800
      end_address: 0x84000
      region: flash_primary
      size: 0x73800
    bootconf:
      address: 0xffd080
      end_address: 0xffd084
      region: bootconf
      size: 0x4
    mcuboot:
      address: 0x0
      end_address: 0x10000
      placement:
        align:
          end: 0x1000
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0x10000
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10800
      placement:
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x800
    mcuboot_primary:
      address: 0x10000
      end_address: 0x84000
      orig_span: &id001
      - app
      - mcuboot_pad
      region: flash_primary
      sharers: 0x1
      size: 0x74000
      span: *id001
    mcuboot_primary_app:
      address: 0x10800
      end_address: 0x84000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x73800
      span: *id002
    mcuboot_secondary:
      address: 0x84000
      end_address: 0xf8000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x74000
    otp:
      address: 0xffd500
      end_address: 0xffd980
      region: otp
      size: 0x480
    sram_primary:
      address: 0x20000000
      end_address: 0x20030000
      region: sram_primary
      size: 0x30000
    zms_storage:
      address: 0xf9000
      end_address: 0xfd000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x4000
    
    EMPTY_0:
      address: 0xff000
      end_address: 0xff800
      placement:
        after:
        - zms_storage
      region: flash_primary
      size: 0x800
    EMPTY_1:
      address: 0xfa000
      end_address: 0xfb000
      placement:
        after:
        - mcuboot_secondary
      region: flash_primary
      size: 0x1000
    app:
      address: 0x10800
      end_address: 0x85000
      region: flash_primary
      size: 0x74800
    bootconf:
      address: 0xffd080
      end_address: 0xffd084
      region: bootconf
      size: 0x4
    mcuboot:
      address: 0x0
      end_address: 0x10000
      placement:
        align:
          end: 0x1000
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0x10000
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10800
      placement:
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x800
    mcuboot_primary:
      address: 0x10000
      end_address: 0x85000
      orig_span: &id001
      - mcuboot_pad
      - app
      region: flash_primary
      sharers: 0x1
      size: 0x75000
      span: *id001
    mcuboot_primary_app:
      address: 0x10800
      end_address: 0x85000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x74800
      span: *id002
    mcuboot_secondary:
      address: 0x85000
      end_address: 0xfa000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x75000
    sram_primary:
      address: 0x20000000
      end_address: 0x20030000
      region: sram_primary
      size: 0x30000
    zms_storage:
      address: 0xfb000
      end_address: 0xff000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x4000
    
    mcuboot:
      address: 0x0
      end_address: 0x10000
      placement:
        align:
          end: 0x1000
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0x10000
    
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10800
      placement:
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x800
    
    mcuboot_primary:
      address: 0x10000
      end_address: 0x85000
      orig_span: &id001
      - mcuboot_pad
      - app
      region: flash_primary
      sharers: 0x1
      size: 0x75000
      span: *id001
    
    mcuboot_primary_app:
      address: 0x10800
      end_address: 0x85000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x74800
      span: *id002
    
    mcuboot_secondary:
      address: 0x85000
      end_address: 0xfa000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x75000
    
    zms_storage:
      address: 0xfb000
      end_address: 0xff000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x4000
Children
No Data
Related