Защита прошивки от считывания.
Небольшой туториал по защите прошивки микроконтроллера stm32 от считывания

Для защиты прошивки можно применять несколько способов:
- установка битов соответствующих регистров
- и совсем варварский способ - оторвать ноги JTAG :)
Я предпочитаю исключительно первый способ.
Простейший вариант это подключить контроллер и с помощью утилиты ST-Link Utility изменить настройки Option Bytes, установив Read Out Protection в значение Enable.

Всё, контроллер больше не поддаётся ни отладке, ни считыванию прошивки. И самое прекрасное, что при снятии этого флага память программы очищается.
Для автоматизации можно конечно написать скрипт, который будет сразу заливать прошивку и выставлять нужный нам бит, благо утилита имеет консольную версию.
Но всё можно сделать на много проще.
В библиотеке StdPeriph в файле stm32f10x_flash.h имеется определение функции:
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);
Принимающая на вход значение ENABLE или DISABLE, соответственно включить защиту и выключить.
Получается что для защиты нам необходимо только выполнить эту функцию со значением ENABLE. Но нужно ещё разблокировать запись во флэш. То есть код будет выглядеть следующим образом.
FLASH_Unlock();
FLASH_ReadOutProtection(ENABLE);
FLASH_Lock();
Делаем всё выше сказанное перед (можно после) инициализации всей периферии в процедуре main. Но теперь возникает вопрос - мы будет каждый раз переписывать значение при включении нашего устройства? Нет, для этого необходимо каким-то образом узнать, установлена ли уже защита, на помощь приходит функция из того же файла stm32f10x_flash.h и код уже будет выглядеть следующим образом:
#include "main.h"
#include "stm32f10x_flash.h" // Хедер драйвер для флэша
#define NDEBUG // макрос для разрешения и запрещения отладки
int main(void)
{
#ifdef NDEBUG
#warning "FLASH Read OUT Protection ON. DEBUG is OFF."
// Проверяем установлена или сброшена защита
if (FLASH_GetReadOutProtectionStatus() == RESET)
{
// если защиты нет
FLASH_Unlock(); // Разрешаем запись в память
FLASH_ReadOutProtection(ENABLE); // Защищаемся от считывания прошивки
FLASH_Lock(); // Запрещаем запись в память
}
#endif
init(); // Инициализация
while (1)
{
// Здесь будет ваша программа
}
}
Если же использовать для разработки и прошивки KEIL, то можно просто в настройках проекта установить флаг Execute-only Code и среда всё сделает за вас.
