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

What is a reason of the definite SoftDevice assertion handler: m_line_num: 811; m_p_file_name: src\ll_lm.s0.c

Hello,

We start using of our BLE devices with more or less permanent connection with our central BLE device, it was needed for Alisa connection.

BLE peripherals are old enough devices with SoftDevice S110 v7.0.0 SDK v6.0.0 on nrf51822AA, they are already in production state (that is why we can not change SoftDevice version to more newer).
Central is like a gateway from WiFi to Blutooth and vise versa. (BLE part is on nrf52832AA, S132 v2.0.0, SDK v11.0.0) 

And we found out some troubles of peripherals (resets, hangings) only after we started usage that configuration with permanent connection.
But really there are a lot of BLE disconnections with subsequent recovery a connection (we saw that with RTT Viewer). Then we deepened into the bug problem, and found out the following bug text inside our peripherals:

m_line_num: 811; m_p_file_name: src\ll_lm.s0.c

That was produced by SoftDevice assertion handler.
It was confirmed a few times on two various types of our peripheral BLE devices. To reproduce this bug we were waiting a lot of time (during a few days). 
Also we supposed, that the bug arises at the moments of connection event time.

Q: What is an exact reason of that bug text, and what are your recommnedations in our situation?

Thank you in advance.

Parents
  • Hi,

    It may be related to a an issue in S110v7.0 that was fixed in S110v7.3 (from release notes of v7.3.0): "Fixed an assert that could be triggered if the actual clock accuracy of the peer is lower than what declared in the connect request packet and a packet is received exactly at time out (DRGN-5400)."

    If it only occurs with S132v2.0.0 then I suggest to set lfclk tolerance to 500ppm when init the S132 softdevice (even if the lfclk is better). Also make sure that you include workaround for errata_108() in system_nrf52c, this was not identified when SDKv11 was released. I have attached a newer system file for you.

    /*
    
    Copyright (c) 2009-2018 ARM Limited. All rights reserved.
    
        SPDX-License-Identifier: Apache-2.0
    
    Licensed under the Apache License, Version 2.0 (the License); you may
    not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
        www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an AS IS BASIS, WITHOUT
    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    
    NOTICE: This file has been modified by Nordic Semiconductor ASA.
    
    */
    
    /* NOTE: Template files (including this one) are application specific and therefore expected to
       be copied into the application project folder prior to its use! */
    
    #include <stdint.h>
    #include <stdbool.h>
    #include "nrf.h"
    #include "system_nrf52.h"
    
    /*lint ++flb "Enter library region" */
    
    #define __SYSTEM_CLOCK_64M      (64000000UL)
    
    static bool errata_12(void);
    static bool errata_16(void);
    static bool errata_31(void);
    static bool errata_32(void);
    static bool errata_36(void);
    static bool errata_37(void);
    static bool errata_57(void);
    static bool errata_66(void);
    static bool errata_108(void);
    static bool errata_136(void);
    static bool errata_182(void);
    
    
    #if defined ( __CC_ARM )
        uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
    #elif defined ( __ICCARM__ )
        __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
    #elif defined ( __GNUC__ )
        uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
    #endif
    
    void SystemCoreClockUpdate(void)
    {
        SystemCoreClock = __SYSTEM_CLOCK_64M;
    }
    
    void SystemInit(void)
    {
        /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
           Specification to see which one). */
        #if defined (ENABLE_SWO)
            CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
            NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
            NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
        #endif
    
        /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
           Specification to see which ones). */
        #if defined (ENABLE_TRACE)
            CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
            NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
            NRF_P0->PIN_CNF[14] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
            NRF_P0->PIN_CNF[15] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
            NRF_P0->PIN_CNF[16] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
            NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
            NRF_P0->PIN_CNF[20] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
        #endif
        
        /* Workaround for Errata 12 "COMP: Reference ladder not correctly calibrated" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp */
        if (errata_12()){
            *(volatile uint32_t *)0x40013540 = (*(uint32_t *)0x10000324 & 0x00001F00) >> 8;
        }
        
        /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp */
        if (errata_16()){
            *(volatile uint32_t *)0x4007C074 = 3131961357ul;
        }
    
        /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp */
        if (errata_31()){
            *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13;
        }
    
        /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp */
        if (errata_32()){
            CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
        }
    
        /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp  */
        if (errata_36()){
            NRF_CLOCK->EVENTS_DONE = 0;
            NRF_CLOCK->EVENTS_CTTO = 0;
            NRF_CLOCK->CTIV = 0;
        }
    
        /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp  */
        if (errata_37()){
            *(volatile uint32_t *)0x400005A0 = 0x3;
        }
    
        /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp  */
        if (errata_57()){
            *(volatile uint32_t *)0x40005610 = 0x00000005;
            *(volatile uint32_t *)0x40005688 = 0x00000001;
            *(volatile uint32_t *)0x40005618 = 0x00000000;
            *(volatile uint32_t *)0x40005614 = 0x0000003F;
        }
    
        /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp  */
        if (errata_66()){
            NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
            NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
            NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
            NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
            NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
            NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
            NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
            NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
            NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
            NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
            NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
            NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
            NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
            NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
            NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
            NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
            NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
        }
    
        /* Workaround for Errata 108 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp  */
        if (errata_108()){
            *(volatile uint32_t *)0x40000EE4ul = *(volatile uint32_t *)0x10000258ul & 0x0000004Ful;
        }
        
        /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp  */
        if (errata_136()){
            if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){
                NRF_POWER->RESETREAS =  ~POWER_RESETREAS_RESETPIN_Msk;
            }
        }
        
        /* Workaround for Errata 182 "RADIO: Fixes for anomalies #102, #106, and #107 do not take effect" found at the Errata document
           for your device located at https://infocenter.nordicsemi.com/index.jsp  */
        if (errata_182()){
            *(volatile uint32_t *) 0x4000173C |= (0x1 << 10);
        }
        
        /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
         * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
         * operations are not used in your code. */
        #if (__FPU_USED == 1)
            SCB->CPACR |= (3UL << 20) | (3UL << 22);
            __DSB();
            __ISB();
        #endif
    
        /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
           two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
           normal GPIOs. */
        #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
            if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NVIC_SystemReset();
            }
        #endif
    
        /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
          defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
          reserved for PinReset and not available as normal GPIO. */
        #if defined (CONFIG_GPIO_AS_PINRESET)
            if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
                ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_UICR->PSELRESET[0] = 21;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_UICR->PSELRESET[1] = 21;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
                NVIC_SystemReset();
            }
        #endif
    
        SystemCoreClockUpdate();
    }
    
    
    static bool errata_12(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
                return true;
            }
        }
    
        return false;
    }
    
    static bool errata_16(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
        }
    
        return false;
    }
    
    static bool errata_31(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
                return true;
            }
        }
    
        return false;
    }
    
    static bool errata_32(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
        }
    
        return false;
    }
    
    static bool errata_36(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
                return true;
            }
        }
    
        return false;
    }
    
    static bool errata_37(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
        }
    
        return false;
    }
    
    static bool errata_57(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
        }
    
        return false;
    }
    
    static bool errata_66(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
                return true;
            }
        }
    
        return false;
    }
    
    
    static bool errata_108(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
                return true;
            }
        }
    
        return false;
    }
    
    
    static bool errata_136(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
                return true;
            }
        }
    
        return false;
    }
    
    
    static bool errata_182(void)
    {
        if (*(uint32_t *)0x10000130ul == 0x6ul){
            if (*(uint32_t *)0x10000134ul == 0x6ul){
                return true;
            }
        }
    
        return false;
    }
    
    
    /*lint --flb "Leave library region" */
    

    Best regards,
    Kenneth

  • Thank you very much Kenneth,

    May be you are right, but we also interested in exact reason of the bug m_line_num: 811; m_p_file_name: src\ll_lm.s0.c
    In that situation we will waiting your additional information.

    PS
    Sorry for my misunderstanding of your position. :)

  • I am contact with softdevice team to get their input. 

    One question, are you disabling interrupts for any period of time in your code?

  • Hi,

    Yes, there is a very short interruption in one of our two tested projects:
    exactly, two operators inside critical section in function that is called from main cycle, it's like
    CRITICAL_REGION_ENTER(); a = b; b = 0; CRITICAL_REGION_EXIT();

    But another project contains critical region only at advertising initialisation stage (at start of device) one time. I think critical regions is not the cause in our projects because the assertion condition arises in both projects after several hours from starting of devices.

    We are looking forward to answer from softdevice team.
    And that is urgently.

  • Hi,

    It seems to be related to rapid connections and disconnections and consecutive start/stop advertising events. This trigger a race condition between BLE connection/disconnect event, LL procedures and (re-)start of advertisement. Can you for instance try to wait  along period of time (e.g. 6 seconds) from disconnect event until you start advertising again?

    In worst case you may need to consider disable and re-enable the SoftDevice after each disconnect to avoid the assert.

    Kenneth

  • Hi,

    Firstly, thanks for your advice. My intuition says to me that this is a right way.

    We started a test with delayed advertising after disconnected event (in two types of our devices), as you adviced us. We checked advertising data in Master Control Panel, and we saw the 6s pause in advertising data after disconnected event (we output counters of connected/disconnected events into advertising data and RTC1 counter too). It works as you suggested. And we will wait some result during a few days.

    Only one question. Why 6 seconds? It maybe long enough time for our clients to restore a connection for device control. What is a reason for this time value, can we reduce this delay time to 0.5s for example?

    Best regards

  • Hi,

    I believe the reasoning behind the long delay are related to the supervisor timeout of the previous link.

    Kenneth

Reply Children
  • Hi,
    Unfortunately, one of the tested Peripheral devices wrote at RTT Viewer the same assertion handler string after 41 hours of work:
    m_line_num: 789; m_p_file_name: src\ll_lm.s0.c
    We suppose next step with disable/enable Softdevice, as you adviced.

    .......

    It has passed 3 hours yet. And the bug happens in the second type of our Peripheral device with the same text too:

    m_line_num: 789; m_p_file_name: src\ll_lm.s0.c

Related