2017-08-07 03:40 AM
Are there any examples of enabling (level 1) and disabling code readout protection for stm32f7?
I have just tried this on an stm32f767 based on code that worked for stm32f4xx and I seem to have 'bricked' the microcontroller - my Rowley Crossconnect JTAG debugger cannot connect any more.
Enabling read-out protection with the following sequence seemed to work (although I did not get the log message I expected):
__attribute__ ((section('.fast')))
// attribute fast forces this code to be in RAMvoid enableReadProtection(void) { // this is destructive and hangs const char *rommessage = '\nCycle power to complete\n'; char rammessage[40]; char *message; FLASH_Status status = FLASH_COMPLETE; message = strcpy(rammessage, rommessage); logString('Enabling read-out protection: '); flush(); NVIC->ICER[0] = 0xFFFFFFFF; NVIC->ICER[1] = 0xFFFFFFFF; NVIC->ICER[2] = 0xFFFFFFFF; ctl_global_interrupts_set(0);// FLASH_OB_Unlock(); if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET) { /* Authorizes the Option Byte register programming */ FLASH->OPTKEYR = FLASH_OPT_KEY1; FLASH->OPTKEYR = FLASH_OPT_KEY2; } status = FLASH_WaitForLastOperation_Fast(); &sharpif PROCESSOR_FAMILY == PROCESSOR_STM32F4 if(status == FLASH_COMPLETE) *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = OB_RDP_Level_1; *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= FLASH_OPTCR_OPTSTRT; &sharpelif PROCESSOR_FAMILY == PROCESSOR_STM32F7 if (status == FLASH_COMPLETE) *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = OB_RDP_LEVEL_1; FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT; &sharpendif /* PROCESSOR_FAMILY */ /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation_Fast(); // FLASH_OB_Lock(); FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; // indicate completion USART_TypeDef *usart_log = (USART_TypeDef *)bootloader_debug_usart; while ((usart_log->USART_ISR_REGISTER & USART_ISR_REGISTER_TC) == 0) { ; } usart_log->USART_TDR_REGISTER = '0' + status; while (*message != '\0') { while ((usart_log->USART_ISR_REGISTER & USART_ISR_REGISTER_TC) == 0) { ; } usart_log->USART_TDR_REGISTER = *message++; } while (1) { // wait forever for manual power-cycling __asm__ __volatile__ (' nop\n nop\n nop\n'); }}And at this point I could disconnect and reattach the debugger. Although (of course) I was unable to download fresh code to FLASH.So now I tried the following code (I couldn't find any examples directly aimed at readout protection in the Cube examples for F7 v1.7.0 so I loosely based it on the FLASH_PcropProtection example)
uint32_t SystemCoreClock;
int main(void) { &sharpif PROCESSOR_FAMILY == PROCESSOR_STM32F4 FLASH_Status protector; FLASH_OB_Unlock(); FLASH_OB_WRPConfig(OB_WRP_Sector_All, DISABLE); /* protector = */FLASH_OB_RDPConfig(OB_RDP_Level_0); protector = FLASH_OB_Launch(); FLASH_OB_Lock(); logU(protector); &sharpelif PROCESSOR_FAMILY == PROCESSOR_STM32F7 SystemCoreClock = 16000000; HAL_InitTick(TICK_INT_PRIORITY); HAL_StatusTypeDef protector; FLASH_OBProgramInitTypeDef obInit; /* Allow Access to option bytes sector */ HAL_FLASH_OB_Unlock(); /* Allow Access to Flash control registers and user Flash */ HAL_FLASH_Unlock(); obInit.OptionType = OPTIONBYTE_RDP; obInit.WRPState = OB_RDP_LEVEL_0; HAL_FLASHEx_OBProgram(&obInit); /* Start the Option Bytes programming process */ protector = HAL_FLASH_OB_Launch(); /* Prevent Access to option bytes sector */ HAL_FLASH_OB_Lock(); /* Disable the Flash option control register access (recommended to protect the option Bytes against possible unwanted operations) */ HAL_FLASH_Lock(); logU(protector); &sharpendif /* PROCESSOR_FAMILY */ logString(' Unlock Complete\n'); return 0;}And from that point on I couldn't attach / reattach the debugger. I've tried wiring BOOT0 to Vdd. So I guess this particular processor is 'bricked' (much as if I put readout protection to level 2).
For now I shall move to my next board, and (unless people can give any other suggestions) arrange to have a new processor fixed to my first board.
But am I doing wrong?
What should I be doing the set readout protection to level 1 and then back to level 0?
- Danish
#stm32f7 #flash-rdp2017-08-07 06:16 AM
Hi
Ali.Danish
,Are you able to connect to your board and unlock it using the STLink Utility?
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2017-08-07 08:38 AM
Thanks for your interest.
I haven't tried ST-Link because:
One other thing I have not tried (but might be possible) is to tie BOOT0 high and see if I can connect over e.g. RS232 using the STM32 bootloader protocol. But I would have thought that when executing from the bootloader from power-on, JTAG should (to some extent) be enabled. Unless code-readout-protection level 2 was somehow invoked.
Does the bootloader spontaneously emit anything on coming-out-of reset on any of the interfaces, or only in response to incoming signals? (So I could look for activity on a specific pin with 'scope).
- Danish
2018-05-07 01:04 PM
Ran into the very same problem recently with an STM32F303.
Its reference manual mentions:
'
If the read protection is set while the debugger is still connected through JTAG/SWD, apply a POR (power-on reset) instead of a system reset.
'The solution is therefore to turn off the power to the STM32, and then turn it back on. Your firmware will then run just as well as before.2018-05-07 01:51 PM
Hi Danish,
From your example you might be using an uninitialised structure:
FLASH_OBProgramInitTypeDef obInit; /* Allow Access to option bytes sector */
HAL_FLASH_OB_Unlock(); /* Allow Access to Flash control registers and user Flash */ HAL_FLASH_Unlock(); obInit.OptionType = OPTIONBYTE_RDP; obInit.WRPState = OB_RDP_LEVEL_0; HAL_FLASHEx_OBProgram(&obInit); /* Start the Option Bytes programming process */obInit structure is as follows:
typedef struct{ uint32_t OptionType; /*!< Option byte to be configured. This parameter can be a value of @ref FLASHEx_Option_Type */ uint32_t WRPState; /*!< Write protection activation or deactivation. This parameter can be a value of @ref FLASHEx_WRP_State */ uint32_t WRPSector; /*!< Specifies the sector(s) to be write protected. The value of this parameter depend on device used within the same series */ uint32_t Banks; /*!< Select banks for WRP activation/deactivation of all sectors. This parameter must be a value of @ref FLASHEx_Banks */ uint32_t RDPLevel; /*!< Set the read protection level. This parameter can be a value of @ref FLASHEx_Option_Bytes_Read_Protection */ uint32_t BORLevel; /*!< Set the BOR Level. This parameter can be a value of @ref FLASHEx_BOR_Reset_Level */ uint8_t USERConfig; /*!< Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. */} FLASH_OBProgramInitTypeDef;it's likely that the other fields in the structure are not set correctly.
did you resolve your problem?
Regards, Kirem