cancel
Showing results for 
Search instead for 
Did you mean: 

Read out protection is causing complete shutdown of STM32L476ZET6 MCU on field

ankitzpatel
Associate

Hello everyone / @all 

We have STM32L476ZET6 in our Vehicle Gateway product with low power mode (STOP2) enabled.

In one of the binary release, we are writing some data at first page of Flash Bank 2 starting from 0x0x08070000 just after initialization in main function.

Below is the pseudo code:

int API_TO_WRITE_OR_UPDATE_FLASH(int data)
{
static FLASH_EraseInitTypeDef erase_conf;
FLASH_If_WriteProtectionClear();
HAL_FLASH_Unlock();
update "erase_conf" with proper Banks, Page, NbPages
HAL_FLASHEx_Erase(&erase_conf, &page_err);
HAL_FLASH_Lock();
FLASH_If_Write((0x08070000 + (7 * 2048)),&data,sizeof(data));
}
 
int main(void)
{
HAL_Init();
HAL_Delay(250);
SystemClock_Config();
init_app();
MX_GPIO_Init();
... (few more I2C, TIM inits)
 
int flash_read_data = API_TO_READ_FROM_FLASH();
int retry_cnt = 3;
while(retry_cnt){
API_TO_WRITE_OR_UPDATE_FLASH(flash_read_data+1);
}
}
 

Now, when we performed OverTheAir upgrade of binary.bin where few hardware observeed extreme power fluctuations (more than 10-20times a second) and somehow MCU stops working. So we have to physically visit the location and connect ST-Link debugger which shows RDP got enabled with FF value. When set RDP to 0, it turned entire flash content to FF so we had to reflash the MCU with the help of ST-Link debugger

ankitzpatel_0-1693308511484.png

ankitzpatel_1-1693308585141.png

ankitzpatel_2-1693308616346.png

ankitzpatel_3-1693308637175.png

We got to learn from the detailed debugging that severe power fluctuation at the time of Flash write operation during init causing this. Once RDP is getting enabled our MCU stops executing which we confirm with attached LED over GPIOs. Since we found no way to revive this devices except recovering with the help of ST-Link debugger (setting RDP AA / Level 0 and reflash) which is not feasible solution so We want to understand what other possible operations can cause the similar behavior for that we can take preventive actions.

Any pointers for the list of actions which can Enable RDP ?

Thanks in advance,

Ankit Vaghasiya

3 REPLIES 3
TDK
Guru

> FLASH_If_WriteProtectionClear();

This function name didn't match any ST code. I'd investigate here. It's definitely changing option bytes.

https://github.com/search?q=repo%3ASTMicroelectronics%2FSTM32CubeL4%20FLASH_If_WriteProtectionClear&type=code

Bottom line, perhaps run the power fluctuations to ground as those seem to be the source of the issue. Perhaps look at BOR settings or some other way to interrupt execution if power is unstable.

 

> FLASH_If_Write((0x08070000 + (7 * 2048)),&data,sizeof(data));

Data length must be a multiple of 64 bits. You're only writing 32 here.

> In one of the binary release, we are writing some data at first page of Flash Bank 2 starting from 0x0x08070000 just after initialization in main function.

First page of bank 2 is at 0x08040000.

If you feel a post has answered your question, please click "Accept as Solution".

Hello @TDK 

Thank you for the prompt response. Your guesses were spot on and helped us a lot.

We wrote API FLASH_If_WriteProtectionClear() API to call before any Flash Erase/update operations

uint32_t FLASH_If_WriteProtectionClear( void )
{
FLASH_OBProgramInitTypeDef OptionsBytesStruct1;
HAL_StatusTypeDef retr;

 /* Unlock the Flash to enable the flash control register access */
retr = HAL_FLASH_Unlock();

 /* Unlock the Options Bytes */
retr |= HAL_FLASH_OB_Unlock();

// OptionsBytesStruct1.RDPLevel = OB_RDP_LEVEL_0;
OptionsBytesStruct1.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct1.WRPArea = OB_WRPAREA_BANK2_AREAA;
OptionsBytesStruct1.WRPEndOffset = 0x00;
OptionsBytesStruct1.WRPStartOffset = 0xFF;
retr |= HAL_FLASHEx_OBProgram(&OptionsBytesStruct1);

OptionsBytesStruct1.WRPArea = OB_WRPAREA_BANK2_AREAB;
retr |= HAL_FLASHEx_OBProgram(&OptionsBytesStruct1);

HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();

return (retr == HAL_OK ? FLASHIF_OK : FLASHIF_PROTECTION_ERRROR);
}

please consider data size and Flash Bank 2 address as typo because indeed data size is 64bits and FlashBank2 address is 0x08070000. I have updated pseudocode below

int API_TO_WRITE_OR_UPDATE_FLASH(int val)
{
   uint32_t data = val;
   static FLASH_EraseInitTypeDef erase_conf;
   FLASH_If_WriteProtectionClear();
   HAL_FLASH_Unlock();
   ... update "erase_conf" with proper Banks, Page, NbPages
   HAL_FLASHEx_Erase(&erase_conf, &page_err);
   HAL_FLASH_Lock();
   FLASH_If_Write((0x08070000 + (7 * 2048)),&data,sizeof(data));
}

int main(void)
{
   HAL_Init();
   HAL_Delay(250);
   SystemClock_Config();
   init_app();
   MX_GPIO_Init();
   ... few more I2C, TIM inits

   int flash_read_data = API_TO_READ_FROM_FLASH();
   int retry_cnt = 3;
   while(retry_cnt){
      API_TO_WRITE_OR_UPDATE_FLASH(flash_read_data+1);
      int flash_read_updated_data = API_TO_READ_FROM_FLASH();
      if(flash_read_updated_data == flash_read_data)
         break;
      retry_cnt--;
   }
}

In past we observed write protection related issue in normal run and introduce addition check before flash operations which helped us by resolving Flash protection issues.

Now if we remove "FLASH_If_WriteProtectionClear()" call prior to Flash write, we do not observe issue during extreme power fluctuations but issue persist with code posted above.

Can you please further assist us with why execution of FLASH_If_WriteProtectionClear(); during power fluctuation can cause RDP gets enable? and How to avoid RDP protection getting enabled and entire Flash turning FF in all possible cases?

Thank you,

Ankit

TDK
Guru

Hmm, I'm not really sure.

I would suggest putting HAL_FLASHEx_OBGetConfig calls after each modification of the option bytes to see where it happens. And if you can isolate where it happens, step through the HAL code to ensure it's doing the right things.

We could be missing something here.

If you feel a post has answered your question, please click "Accept as Solution".