Иногда нужно заблокировать считывание прошивки из МК. Причины могут быть разные. Не об этом сейчас речь.
Чтобы включить защиту нужно после прошивки в STM32 ST-LINK Utility, открыть окно "Option bytes" и в выпадающем списке "Read Out Protection" выбрать нужный уровень защиты.
В этом окне можно изменить другие настройки, такие как метод запуска сторожевого таймера (аппаратно при старте или программно), откуда запускать загрузчик (из Flash или ОЗУ), включить защиту от записи страниц Flash и т. д. Вообще это аналог фьюзов AVR, только назвывается по другому.
Так вот. Предусмотрены три уровня защиты прошивки.
Level 0: no protection
Read, program and erase operations into the main Flash memory area are possible.
The option byte are as well accessible by all operations.Level 1: read protection
This is the default protection level when RDP option byte is erased. It is defined as well
when RDP value is at any value different from 0xAA and 0xCC, or even if the complement is
not correct.
• User mode: Code executing in user mode can access main Flash memory and option
byte with all operations.
• Debug, boot RAM and boot loader modes: In debug mode (with SWD) or when code
is running from boot RAM or boot loader, the main Flash memory is totally inaccessible.
In these modes, even a simple read access generates a bus error and a Hard Fault
interrupt. The main Flash memory is program/erase protected to prevent malicious or
unauthorized users from reprogramming any of the user code with a dump routine. Any
attempted program/erase operation sets the PGERR flag of Flash status register
(FLASH_SR).
When the RPD is reprogrammed to the value 0xAA to move back to Level 0, a mass
erase of the main Flash memory is performed.Level 2: no debug
In this level, the protection level 1 is guaranteed. In addition, the CortexM0 debug
capabilities are disabled. Consequently, the debug port (SWD), the boot from RAM (boot
RAM mode) and the boot from System memory (boot loader mode) are no more available.
In user execution mode, all operations are allowed on the Main Flash memory. On the
contrary, only read and program operations can be performed on the option byte. Option
byte are not accessible for erase operations.
Moreover, the RDP byte cannot be programmed. Thus, the level 2 cannot be removed at all:
it is an irreversible operation. When attempting to program the RDP byte, the protection
error flag WRPRTERR is set in the Flash_SR register and an interrupt can be generated.
Note: The debug feature is also disabled under reset.
STMicroelectronics is not able to perform analysis on defective parts on which the level 2
protection has been set.
Если кратко то уровни защиты отличаются следующим.
Level 0: - защита прошивки отключена.
Level 1: - содержимое Flash недоступно через отладочный интерфейс, программе загрузчика и выполняемой из ОЗУ.
Level 2: - получаем "кирпич" поскольку отключается отладочный интерфейс и встроенный загрузчик. Отключить этот уровень защиты нельзя. Дальнейшее перепрограммирование МК невозможно.
Изменить уровень защиты в окне программы сложностей не представляет и об этом нет смысла рассказывать. Больший интерес представляет программное включение защиты прошивки. Причем таким методом часто пользуются. Например он применен в отладчике ST-Link.
Схема тестового устройства.

При включении, если защита выключена (Level 0) то она будет включена (Level 1) и светодиод несколько раз мигнет, а если при включении будет обнаружено что защита прошивки уже включена, то светодиод мигнет только раз.
Функция включения защиты
void OptioisBytes(void)
{
if (FLASH_OB_GetRDP() == RESET) // Проверяем включена ли защита от чтения.
{ // И если защита выключена то включим ее.
FLASH_Unlock(); // Разрешаем запись во Flash.
FLASH_OB_Unlock(); // Разрешаем доступ к option bytes.
// OB_RDP_Level_0: No protection
// OB_RDP_Level_1: Read protection of the memory
// OB_RDP_Level_2: Chip protection !!!!!!!!!!!!!!!!!! ОСТОРОЖНО, НЕОБРАТИМО ЗАЛОЧЕННЫЙ МК !!!!!!!!!!
if (FLASH_OB_RDPConfig(OB_RDP_Level_1) == FLASH_COMPLETE)
{
// Защита от чтения успешно включена - мигаем светодиодом.
for (uint8_t i=0; i<=4; i++)
{
GPIO_SetBits(GPIOB, GPIO_Pin_1); // Лог 1 на выходе.
SysTim_DelayMS(100);
GPIO_ResetBits(GPIOB, GPIO_Pin_1); // Лог 0 на выходе.
SysTim_DelayMS(100);
}
FLASH_OB_Launch(); // При выполнении функции МК перезагрузится!
}
FLASH_OB_Lock(); // Запрещаем доступ к option bytes.
FLASH_Lock(); // Запрещаем запись во Flash.
}
}Функция FLASH_OB_GetRDP вернет RESET если защита выключена, и не RESET если включена. В последнем случае, функция на этом завершается. Если же защита выключена то происходит следующее: Функции FLASH_Unlock() и FLASH_OB_Unlock() разрешают запись во Flash и изменение "Option bytes" соответственно. Далее функция FLASH_OB_RDPConfig() устанавливает уровень защиты "Level 1" и если ей это удается, то она вернет FLASH_COMPLETE. Далее в цикле мигает светодиод и после этого функция FLASH_OB_Launch() применяет изменения. При этом произойдет перезапуск МК.
Если прошить МК и запустить прошивку, то при первом запуске светодиод несколько раз мигнет, а при следующих запусках только один раз. В окне "Option bytes" видно что активен уровень защиты "Level 1".

Если попытаться прочитать содержимое Flash, то ничего не выйдет.

Чтобы получить доступ к Flash нужно в окне "Option bytes" в выпадающем списке "Read Out Protection" выбрать уровень защиты "Level 0" и сохранить его. Это естественно приведет к полной очистке Flash.
