Гипотетическая ситуация следующая - у нас есть устройство до которого очень тяжело дотянуться ручками, но есть доступ к загрузчику. И нужно установить некоторые OB, например, управление ножками бута или установка защиты от чтения.
Для того, чтобы OB встали на свое место - необходим перезапуск МК. Причем, простого ребута по вочдогу или через NVIC_SystemReset() будет недостаточно. Нужен именно Power Cycle всей внутренней периферии. Мы предполагаем, что у нас уже заведен watchdog, который "разбудит" МК перезагрузкой или включены часы RTC с ножкой WakeUp. Разницы особой нет. Вся соль применения Option Bytes без физической перезагрузки - именно в переходе в режим ожидания.
В коде мы проверяем - был ли ранее выставлен необходимый режим работы с OB (в примере RDP 1 и отключение физической ножки перехода в загрузчик). Если нет - то включаем его и ждем ребута.
Код для справки:
int check_rdp(void){
FLASH_OBProgramInitTypeDef OBInit = {0};
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_OBGetConfig(&OBInit);
//Если RDP не установлен, то устанавливаем
if(OBInit.RDPLevel == OB_RDP_LEVEL_0){
OBInit.OptionType = OPTIONBYTE_USER | OPTIONBYTE_RDP;
OBInit.USERType = OB_USER_nBOOT0 | OB_USER_nSWBOOT0;
OBInit.USERConfig = OB_BOOT0_SET | OB_BOOT0_FROM_OB;
OBInit.RDPLevel = OB_RDP_LEVEL_1;
if (HAL_FLASHEx_OBProgram (&OBInit) != HAL_OK){
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return 0;
}
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
while( HAL_FLASH_OB_Launch()!= HAL_OK)
{
//Переходим в режим ожидания
HAL_PWR_EnterSTANDBYMode();
}
}
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return 1;
}