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

Stable application crashes at address 0x00000000 when I add JLINK_MONITOR_ISR_SES.s but DebugMonitor_IRQn is disabled

Very strange, I have lots of nRF52x experience, but this one has me stumped.

Successfully updated our custom board/application from nRF5_SDK_15.0.0 to latest as indicated below:

Setups:

SDK: nRF5_SDK_16.0.0_98a08e2

SoftDevice: 

FreeRTOS (from SDK)

Segger Embedded Studio (same issue on 4.12 / 4.18 / 4.50)

Windows 10

Custom board


Preprocessor definitions: 

BOARD_CUSTOM

NRF52

NRF52832_XXAA

NRF52_PAN_74

S132

SOFTDEVICE_PRESENT

NRF_SD_BLE_API_VERSION=7

CONFIG_NFCT_PINS_AS_GPIOS

FLOAT_ABI_HARD

INITIALIZE_USER_SECTIONS

NO_VTOR_CONFIG

ARM_MATH_CM4

FREERTOS


After migrating to SKD16, everything works very nicely. It is a reasonably complex application.

We use default flash_placement.xml from SDK16 example applications.

Application passes all of our testing. In Debug mode, NRF_LOG via RTT is active. This all operates fine.

Verified we have excess RAM available to the application. RAM_START=0x20002a98.

   ret_code_t ret_code = sd_ble_enable(p_app_ram_start); returns a start value of 0x20002220  ... so we are good here.

To help me isolate the problem, I have erased my nRF52832 IC, and no longer are using our Bootloader.

Only the Softdevice and Application are being loaded via SES.  


The last to do item was to re-enable our JLINK debug monitor. This is the ONLY change we are making to the application

We use the recommended method, as outlined in https://github.com/NordicPlayground/j-link-monitoring-mode-debugging. We use the 3 files as is unmodified.

We use the SDK16.0.0 branch, and our JLINK options are set to: 

    SetMonModeDebug = 1

    SetMonModeVTableAddr = 0x26000

    We execute NVIC_SetPriority(DebugMonitor_IRQn, _PRIO_SD_LOW);  in our Logger task.

When we do this, our application does not startup up at all, and the SES Debugger shows us at address 0x00000000 ... see attached picture below [Crash.png]

Note also the messaging indicating:   T-bit of XPSR is 0 but should be 1. Changed to 1.

To further isolate the problem, I commented out NVIC_SetPriority(DebugMonitor_IRQn, _PRIO_SD_LOW);  ... but no change...

Very weird ... [DebugMon_Handler] is being compiled in, but not being executed. 

... and all of this causes the SES to fail in loading the application.  I am a bit stymied.

I tried setting early breakpoints in thumb_crt0.s ... but it would not hit any of the early breakpoints.


As a very last investigative step, I took the SDK 16.0.0 example application, and modified it to support JLINK_MONITOR ...

... after some tweaking ... works like a charm :}


Free beer to whoever can solve my problem :}

  • Thanks for taking a look. I use my nRF52-DK as my sole JLink device. Has worked very well for me for a long time. Also, I have my demo SDK16 hrs/freertos application where I have Monitor Mode working nicely. 

    For my custom board/application, all my hardware peripherals are at sdk_config.h default level, which is 6

    SDK15 previously had these defaults at 7 ... but I don't see any consequence with the Jlink.

    I did a complete Chip Erase ... so I presume that removed the MBR.

  • I checked into J-Link installations. SES was reporting that it was using V6.54c DLL.

    But the firmware was upgraded, and looking on my disk, I saw there was a V6.62b installation, along with some older 6.20, 6.40 versions. I started thinking maybe the nRF52-DK JLink firmware recently installated may not be compatible with older JLINK DLLs.

    So I cleaned up my whole PC, and uninstalled older J-Link installations.

    In addition, I have 3 SES installations (4.12 / 4.18 / 4.50), they seem to have their own DLLs.

    So I ran JLinkDLLUpdater.exe, and now all my installations are running 6.62b.

    See info below ... Behavior is much the same. The only difference, is that rather than crashing at address 0x00000000, it is on another planet at 0xEA6AAA2C

  • Definitely something in Segger doing something weird ...

    If I have SetMonModeDebug = 0, I can set a breakpoint in thumb_crt0.s right below _start:

    It breaks, and I can step through it, and launch into main()


    But if SetMonModeDebug = 1, it won't even break at _start:

    ... might have to up this to 2 beers ...

  • ... I have to presume that message "T-bit of XPSR is 0 but should be 1" has to be a big hint ...

  • Yes, the chip erase removes the MBR. So .. this is worrying:

      .word   PDM_IRQHandler
      .word   0                           /*Reserved */
      .word   0                           /*Reserved */
      .word   MWU_IRQHandler

    These are not reserved vectors, but they track to address 0x00000000. I have the following in the diagnostics I wrote:


    //  Text Name               V  ID Peripheral Description                                      Base Addr
    //  ==================     == === ========== ================================================ =========================================================
       "PDM",               // 45  29 PDM        Pulse Density Modulation (Digital Microphone)    0x4001D000 PDM_IRQHandler
       "NVMC",              // 46  30 NVMC       Non-Volatile Memory Controller                   0x4001E000 0                         ; Reserved
       "PPI",               // 47  31 PPI        Programmable Peripheral Interconnect             0x4001F000 0                         ; Reserved
       "MWU",               // 48  32 MWU        Memory Watch Unit                                0x40020000 MWU_IRQHandler

    Maybe these vectors need populating; I do thus:

     __WEAK void PDM_IRQHandler(void)       {NVIC_DisableIRQ(PDM_IRQn); NVIC_ClearPendingIRQ(PDM_IRQn); ExceptionVectors.Counters.IrqCount_PDM ++;} // 29 PDM  Pulse Density Modulation (Digital Microphone) 0x4001D000
    __WEAK void Reserved30_IRQHandler(void) {NVIC_DisableIRQ(U30_IRQn); NVIC_ClearPendingIRQ(U30_IRQn); ExceptionVectors.Counters.IrqCount_NVMC++;} // 30 NVMC Non-Volatile Memory Controller                0x4001E000
    __WEAK void Reserved31_IRQHandler(void) {NVIC_DisableIRQ(U31_IRQn); NVIC_ClearPendingIRQ(U31_IRQn); ExceptionVectors.Counters.IrqCount_PPI ++;} // 31 PPI  Programmable Peripheral Interconnect          0x4001F000
    __WEAK void MWU_IRQHandler(void)        {NVIC_DisableIRQ(MWU_IRQn); NVIC_ClearPendingIRQ(MWU_IRQn); ExceptionVectors.Counters.IrqCount_MWU ++;} // 32 MWU  Memory Watch Unit                             0x40020000
     

    I forget why the source does not specify the missing vectors - why are they reserved? They don't have specific enable/disable interrupt registers I see  .. and I don't actually always add them:

    .weak Reserved30_IRQHandler
    .thumb_set Reserved30_IRQHandler, Dummy_Handler
    
    .weak Reserved31_IRQHandler
    .thumb_set Reserved31_IRQHandler, Dummy_Handler
    
      .word   PDM_IRQHandler
      .word   Reserved30_IRQHandler        /*Reserved */
      .word   Reserved31_IRQHandler        /*Reserved */
      .word   MWU_IRQHandler

Related