
Гипотетическая ситуация следующая – у нас есть устройство до которого очень тяжело дотянуться ручками, но есть доступ к загрузчику. И нужно установить некоторые 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; }
Comment