cancel
Showing results for 
Search instead for 
Did you mean: 

J-link debugger cannot connect after enabling secure user memory

aco990
Associate III

Hello everyone,

I am working with the STM32H7B3 and after enabling the secure user memory, i am not able to connect with the debugger anymore:

For testing if secure user memory works, i put a "secure_function" in a section at the end of my flash, then enabled the secure user memory for that section and called the function from the unsecure area (which should result to a bus fault). The questions are:

1. What did i wrong?

2. Why can i not connect to the board which the jlink debugger? I didn't change any option byte except the security OB.

Also i don't thing that the program got stuck in the secure area, because the unsecure area should run first after reset (see code below).

 

Console output:

aco990_0-1716981945739.png

 


Here is the code i used to configure the secure user memory:

 

 

 

 

void __attribute__((__section__(".secureareatest"))) secure_function(){
  count++;
}


bool setSecureUserMemoryProtection(FLASH_OBProgramInitTypeDef& flash_option_bytes) {
  const uint32_t secure_area_start = (0x81FDFFF >> 8U) << 8U;    // shift needed for 256 bytes granularity

  RSS_SecureArea_t aSecureAreas[2];

  if (check_secure_memory_protection(flash_option_bytes)) {
    return true;
  } else {
    if ((flash_option_bytes.USERConfig & FLASH_OPTSR_SECURITY) == RESET) {
      flash_option_bytes.Banks = FLASH_BANK_1;
      flash_option_bytes.OptionType = OPTIONBYTE_USER;
      flash_option_bytes.USERType = OB_USER_SECURITY;
      flash_option_bytes.USERConfig = OB_SECURITY_ENABLE;

      if (HAL_FLASHEx_OBProgram(&flash_option_bytes) == HAL_OK) {
        /*
        Security bit set.
        We need to reload the OBs before configuring the secure user memory area,
        otherwise the configuration is skipped because Secure Mode is not entered at reset (not booting in RSS).
   */
        if(HAL_FLASH_OB_Launch() != HAL_OK){
          return false;
        }
      } else{
        return false;
      }
    }

    /* Set the secure user memory area */

    aSecureAreas[0].sizeInBytes = 8 * 1024;
    aSecureAreas[0].startAddress = secure_area_start;
    aSecureAreas[0].removeDuringBankErase = 1;
    /* Only 1 secure area is used */
    aSecureAreas[1].sizeInBytes = 0U;
    aSecureAreas[1].startAddress = 0U;
    aSecureAreas[1].removeDuringBankErase = 1U;

    RSS_API->resetAndInitializeSecureAreas(1, aSecureAreas);
  }
}

int main(){
   FLASH_OBProgramInitTypeDef flash_option_bytes;
   HAL_FLASH_Unlock();
   __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_ALL_ERRORS_BANK1);
   HAL_FLASH_OB_Unlock();

   flash_option_bytes.Banks = FLASH_BANK_1; 
   HAL_FLASHEx_OBGetConfig(&flash_option_bytes);        
                                          
   set_secure_user_memory_protection(flash_option_bytes);

   while (true) {
     secure_function();
  }
}

        

 

 

 

@Fred 


@Jocelyn RICARD 

1 ACCEPTED SOLUTION

Accepted Solutions
Jocelyn RICARD
ST Employee

Hello @aco990 ,

the secure area does not work as you describe.

Please read reference manual RM0455 Chapter 5. You will see that when defining a secure area, the boot address must be inside this area.

You can thing of secure memory as the location where you put your boot code. Then you close the secure area and jump to your application code. The secure area becomes invisible until next reset.

Another point: when defining a secure area, the JTAG is automatically disabled at boot time.

It can be re-enabled by the code running inside the secure area or at the time you jump out of secure area using the RSS service exitSecureArea.

So, even if you are in RDP Level 0, your chip is bricked. 

I have provided a zip file containing test code in another post taking about same subject. It was for H573 as far as I remember so may need some small adaptations.

Best regards

Jocelyn

 

View solution in original post

4 REPLIES 4
Jocelyn RICARD
ST Employee

Hello @aco990 ,

the secure area does not work as you describe.

Please read reference manual RM0455 Chapter 5. You will see that when defining a secure area, the boot address must be inside this area.

You can thing of secure memory as the location where you put your boot code. Then you close the secure area and jump to your application code. The secure area becomes invisible until next reset.

Another point: when defining a secure area, the JTAG is automatically disabled at boot time.

It can be re-enabled by the code running inside the secure area or at the time you jump out of secure area using the RSS service exitSecureArea.

So, even if you are in RDP Level 0, your chip is bricked. 

I have provided a zip file containing test code in another post taking about same subject. It was for H573 as far as I remember so may need some small adaptations.

Best regards

Jocelyn

 

Thank @Jocelyn RICARD

could you provide some code example on how to re-enable JTAG in the secure area?

In Development Mode, the first think i want to do in the bootloader is to re-enable JTAG and Not wait until i call exitSecureArea. Because my bootloader is in Development Mode i want to be careful because if there is any problem and the program stuck before calling exitSecureArea or Even if exitSecureArea doesn‘t jump to my App i will brick the next board.

I want something Like follwing in my bootloader code to be more careful, also do you think it‘s a good idea to enable it there in dev mode?

void main (){
// re-enable jtag, this could help me to recover any time in Development 

// continue boot process 

exitSecureArea(…) 
}

 

 

Jocelyn RICARD
ST Employee

Hello @aco990 ,

 

here it is:

	__HAL_RCC_GPIOA_CLK_ENABLE();

	/* Disable the DAP protections, so enable the DAP re-configuring SWCLK and SWDIO GPIO pins */
	GPIO_InitStruct.Pin = GPIO_PIN_14;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_PULLDOWN;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Alternate = GPIO_AF0_SWJ;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	GPIO_InitStruct.Pin = GPIO_PIN_13;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 

As you can see this is only SWD re-enabling. If you use JTAG you should do the same: Set corresponding GPIO to their reset value.

Best regards

Jocelyn

thanks @Jocelyn RICARD