Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Unresponsive device when flashing after disabling APPPROTECT

Hi,

I'm developing on the current setup:

  • nRF52840
  • Soft Device 140 version 7.2.0
  • SDK 17.1.0 
  • MDK: 8.51
  • Segger v4.52c
  • Secure bootloader (DFU)

I don't define ENABLE_APPROTECT in the preprocessor and I've followed this guide: Working with the nRF52 Series' improved APPROTECT - Blogs - Nordic Blog - Nordic DevZone, which led me to included this code as the first thing main executes:

void approtect_disable( void )
{
	if ( ( NRF_UICR->APPROTECT & UICR_APPROTECT_PALL_Msk ) != ( UICR_APPROTECT_PALL_HwDisabled << UICR_APPROTECT_PALL_Pos ) ) {

		NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
		while ( NRF_NVMC->READY == NVMC_READY_READY_Busy ) {}

		NRF_UICR->APPROTECT = ( ( NRF_UICR->APPROTECT & ~( ( uint32_t )UICR_APPROTECT_PALL_Msk ) ) |
		                        ( UICR_APPROTECT_PALL_HwDisabled << UICR_APPROTECT_PALL_Pos ) );

		NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
		while ( NRF_NVMC->READY == NVMC_READY_READY_Busy ) {}
		NVIC_SystemReset();
	}
	NRF_APPROTECT->DISABLE = APPROTECT_DISABLE_DISABLE_SwDisable;
}

However, it only works partially. Before including this code, each time I tried to download & debug with Segger, I would get the usual message "CTRL-AP indicates that the device is secured. For debugger connection the device needs to be unsecured. Note: unsecuring will trigger a mass erase of the internal flash" from the JLink driver. After accepting, the application would download correctly but as soon as the nRF reset itself (part of the application sequence), I lost all trace information, which was extremely inconvenient.

After including this code, I no longer get the message and traces keep working even after a reset. However, if I try to download & debug again, the code doesn't run and the uC seems to be stuck at a random location:

When in this state, I can do an "Erase all" from Segger or --eraseall from nrfjprog, but it doesn't fix the issue. I can only fix it after I send a "nrfjprog --recover" from the command line. After that, the next Segger download & debug works fine.

What could be the issue?

Thank you!

Parents Reply Children
  • Hi,

    It should be set to 0x5a after the approtect_disable() function has been executed. Can you place a breakpoint after this function call to confirm?

  • The short answer is that it only reaches that point after a recover, and the value is actually 0x5A. If I try to flash again, it will not even reach main, it gets stuck somewhere else. 

    I think I haven't explained myself clearly. I'll try to put a detailed sequence here: 

    • nrfjprog --recover
    • Download & debug from segger. Segger is configured to "Additional Load" other hex files, which are the soft device, Bootloader and dfu settings, in that order.
    • This reaches main and executes without issues.
    • Goes through the approtect_disable function and leaves NRF_APPROTECT->DISABLE in 0x5A and NRF_UICR->APPROTECT in 0xFF.
    • Debugger works too, even through device resets.
    • Stop debugging session
    • Download & Debug again (no prompt to recover)
    • Now the execution never reaches main, it's stuck somewhere that appears invalid code, as I showed in the original post.
    • FORCEPROTECT shows as 1 (0x40000550)
    • NRF_APPROTECT->DISABLE shows as 1 (0x40000558)
    • NRF_UICR->APPROTECT shows as 0xFF (0x10001208)
    • Stop debugging session
    • Download and Debug again. This prompts for a recovery, press OK and now it works.

    So, it seems to be working every other time. I was under the impression that I could only make it work again with "nrfjprog --recover", but now Segger is prompting me for recovery so it seems to work. Not sure what changed.

    Thanks!

  • Thanks for the summary. The UICR will be cleared every time the bootloader FW is loaded. As a result the, the APPROTECT mechansim will not become unlocked until the program reaches the approtect_disable() call in app main(). To confirm this, you can remove the bootloader hex from the "Additional Load" field.

  • Hi Vidar, yes I can confirm that by disabling the "bootloader.hex" Additional Load, it works fine. But we do need to load it.Based on what you said, I modified the bootloader project to run approtect_disable in main and now the issue seems to be gone.

    This would suggest that the bootloader.hex code is running before flashing the app.hex file? Like in-between Additional Loads. Does that make sense? I'm still not sure I understood everything.

  • The bootloader code always executes before the main application. The boot sequence is: MBR -> Bootloader -> SoftDevice -> Application. This means that the APPROTECT will be locked if a debugger attaches to the target after a reset, but before the bootloader branches to the main application.

    Federico said:
    This would suggest that the bootloader.hex code is running before flashing the app.hex file? Like in-between Additional Loads.

    The CPU is halted while the images are loaded. Execution is started after all hex files have been programmed.

Related