41380

[i] Программирование памяти OTP микроконтроллера К1986ВК025

Дата последнего изменения: 25.04.2024 16:58:07

Объём OTP-памяти микросхемы К1986ВК025 составляет 16 Кбайт. В данной памяти хранится загрузочная программа, а оставшийся объём свободен для использования (кроме последнего байта, имеющего специальное назначение – установка защищенных адресных пространств FLASH-памяти и блокировка отладочного интерфейса JTAG). Важно отметить, что первые версии микросхем К1986ВК025 поставлялись с запрограммированной областью OTP стандартной загрузочной программой, но была возможность заказать микросхемы с чистой памятью OTP, чтобы разработать свою загрузочную программу. Микросхемы второй версии, выпускаемые с маркировки (ГГНН) 2140, поставляются строго с незапрограммированной областью OTP.

Со второй ревизии микроконтроллера были зарезервированы дополнительные адреса памяти OTP. Они содержат специальную информацию (рисунок 1 статьи, также отражено в спецификации в п. "Загрузочное OTP и режимы работы микроконтроллера", следует ориентироваться на спецификацию для получения более полных и актуальных сведений).

Рисунок 1 - Описание специальных полей в памяти OTP (источник - спецификация К1986ВК025, версия 0.9.0)

Программирование OTP реализовано на автоматах, необходимо только задать число тактов задержки для формирования пауз 20 нс (биты DELAY_20NS), 50 нс (биты DELAY_50NS) и 1 мкс (биты DELAY_01US) в регистре DELAY_0 и число тактов задержки для формирования паузы 16 мкс (биты DELAY_16US) в регистре DELAY_1. Все последовательности для чтения и программирования через регистровый доступ модуль однократно программируемой памяти формирует самостоятельно.

Помимо программирования, модуль позволяет читать данные из памяти OTP по шине AHB и осуществлять блокировку отладочного интерфейса. Под блокировкой отладочного интерфейса следует понимать следующее: при подаче питания отладочный интерфейс запрещён, и при считывании последнего байта OTP он или разрешается, или остаётся заблокированным

Для корректного чтения данных из OTP по шине AHB необходимо настроить паузу 70 нс (биты DELAY_70NS регистра DELAY_0). При этом значение по сбросу позволяет читать память на частоте до ~14 МГц.

Стоит обратить внимание, что OTP-память имеет две области отображения – одна начинается с адреса 0x0002_0000 и называется BOOT_OTP, другая начинается с адресов 0x7000_0000 и называется OTP_MEM. При размещении данных обращение к OTP-памяти может быть осуществлено по любому из этих базовых адресов. Однако, эти адреса неравнозначны: загрузочная программа запускается с адресов BOOT_OTP, поэтому она должна быть скомпилирована именно для области BOOT_OTP 0x0002_0000. Аналогичное справедливо для всего кода: вызов кода должен осуществляться из тех адресов BOOT_OTP или OTP_MEM, для которых он был скомпилирован.

Чистая OTP-память заполнена 0, и программирование осуществляется записью 1.

Модуль OTP-памяти позволяет осуществить блокировку чтения и блокировку записи областей памяти OTP. Одна область памяти OTP составляет 2048 байт, всего 8 областей от 0 до 7 (область 0 - адреса 0-2047, область 1 - адреса 2048-4095, и так далее). Запрет записи/чтения для каждой области осуществляется однократно, записью 1 в n-ый бит для n-ой области памяти OTP в регистры WRITE_PROTECT_REG и READ_PROTECT_REG (более подробно процедура блокировки чтения/записи приведена в описании регистров WRITE_PROTECT_REG/READ_PROTECT_REG блока контроллера OTP в спецификации). 


В статье описана работа с OTP-памятью, основные особенности разработки загрузочной программы и запись загрузочной программы в память OTP. В конце статьи приложен архив с проектами для среды Eclipse, в котором содержится пример типовой загрузочной программы (Bootloader) и программа, осуществляющая программирование OTP скомпилированной загрузочной программой (Loader).


Также в конце статьи в архиве с примерами для MDR32F02, MDR1206(A)FI доступен проект с примером чтения и программирования слова OTP-памяти (MDR32F02_OTP_Word).


1. Чтение и программирование OTP-памяти

Как было сказано выше, модуль OTP самостоятельно выполняет все операции для программирования памяти и для подготовки модуля необходимо только указать число тактов паузы в соответствующих регистрах для обеспечения требуемых задержек на разных частотах.

Алгоритм чтения байта памяти с помощью модуля OTP:

  1. Проверка защиты чтения данной области в регистре READ_PROTECT.

  2. Ожидание сброса флага BUSY регистра STAT_CTRL в ноль - флаг является индикацией выполнения модулем OTP каких-либо действий.

  3. Запись битового адреса в функциональные биты ADDR регистра RW_CMD. Младшие 3 бита игнорируются, так как чтение осуществляется байтами.

  4. Установка функционального бита WRITE в 0, а READ в 1 регистра RW_CMD (чтение производится только при наличии 0 в поле WRITE и 1 в поле READ, при условии отсутствия защиты выбранной области от чтения. При чтении флаг BUSY устанавливается в 1).

  5. Ожидание сброса флага BUSY регистра STAT_CTRL в ноль.

  6. Чтение байта данных из поля DATA_0[7:0] регистра READ_DATA. В случае ошибки в данных битах установлена константа 0xEF.

Кроме того, модуль OTP позволяет осуществлять чтение не только через регистры, но и непосредственно из областей памяти BOOT_OTP и OTP_MEM по шине AHB - в таком случае ограничения на объём считываемых данных в 1 байт нет, чтение слов требуемой разрядности осуществляется внутренним автоматом модуля.

Алгоритм записи бита памяти в OTP:

  1. Проверка защиты записи данной области в регистре WRITE_PROTECT.

  2. Ожидание сброса флага BUSY регистра STAT_CTRL в ноль.

  3. Запись битового адреса в функциональные биты ADDR регистра RW_CMD.

  4. Запись бита данных в функциональный бит DATA_0 регистра RW_CMD. Если DATA_0=0, запись не производится, так как 0 - это начальное состояние OTP. Записываются 1 без возможности стирания. Также программирование не производится, если выбранная область OTP защищена от записи.

  5. Установка функционального бита WRITE в 1, а READ в 0 регистра RW_CMD (запись производится только при наличии 1 в поле WRITE и 0 в поле READ, при условии отсутствия защиты выбранной области от записи. При записи флаг BUSY устанавливается в 1).

  6. Ожидание сброса флага BUSY регистра STAT_CTRL в ноль.

  7. Опционально - верификация данных с помощью чтения OTP.

Важно обратить внимание, что, не смотря на байтовую адресацию микроконтроллера, адрес в поле ADDR битовый, а не байтовый. При этом запись в OTP аппаратно производится битами, а чтение - байтами, и при чтении 3 младшие бита, записанные в поле ADDR, игнорируются.

Проект MDR32F02_OTP_Word реализует пример чтения, программирования и верификации 32-битного слова в пустую область OTP-памяти (перед запуском примера необходимо проверить, что по адресу 0x000207D0 данные не были ранее записаны - если данные записаны по этому адресу, изменить адрес, на такой, где OTP-память чистая). В качестве источника частоты устанавливается внешний HSE, так как является более точным. Стоит обратить внимание, что без тримминга реальная частота внутреннего HSI составляет порядка 5.4 МГц, и требования к его стабильности не предъявляются, поэтому вместо внутреннего HSI используется более точный внешний HSE.
Для отладки проектов с чистой OTP-памятью необходимо в настройках отладки среды Eclipse указать Debug in RAM, тогда отладчик всегда будет перемещать program counter на начало программы (startup файла).

2. Разработка загрузочной программы для чистой OTP-памяти

Перед программированием чистой OTP-памяти загрузочной программой её необходимо разработать и отладить из других регионов памяти, например, из Flash-памяти. Однако следует учитывать ограничение по объёму памяти OTP в 16 Кбайт (дополнительно с учетом адресов специальных полей).

В качестве шаблона можно, например, взять проект MDR32F02_Template из статьи «Создаем проект для МК К1986ВК025 в IDE Eclipse», и оставить в подключаемых библиотеках SPL только заголовочный файл, где реализован минимально необходимый функционал для разработки программы на регистрах. В архиве в конце статьи для загрузочной программы реализован проект Bootloader, который реализует описанное в спецификации поведение загрузочной программы.

Перед сборкой проекта Bootloader в файле bootloader_config.h необходимо настроить параметры загрузочной программы:
- объявление MCU_REVISION: указать номер ревизии МК - 1 или 2 (см. документ errata);
- объявление USE_BOOTLOADER_VERSION: указать, требуется ли размещать номер версии загрузочной программы в памяти OTP по адресу 0х2_3FDF/0x7000_3FDF (0 - не размещать в OTP, 1 - размещать в OTP).

После разработки кода загрузочной программы и отладки его из Flash-памяти требуется скомпилировать программу для адресного пространства OTP.

В используемом linker-файле link_Flash.ld должна быть объявлена область BOOT_OTP 0x0002_0000:

MEMORY
{
            FLASH     (rx)      : ORIGIN = 0x10000000, LENGTH = 256K
            OTP       (rx)      : ORIGIN = 0x00020000, LENGTH = 16K
            TCMA_RAM  (xrw)     : ORIGIN = 0x80000000, LENGTH = 64K
            TCMB_RAM  (xrw)     : ORIGIN = 0x80010000, LENGTH = 32K
            AHB_RAM   (xrw)     : ORIGIN = 0x20000000, LENGTH = 16K
}

После этого необходимо изменить регион памяти для хранения программы. Для этого достаточно заменить строку с указанием адресов Flash-памяти в качестве региона загрузки:

  REGION_ALIAS("REGION_LOAD",    FLASH);

на строку с указанием адресов области BOOT_OTP в качестве региона загрузки:

  REGION_ALIAS("REGION_LOAD",    OTP);

Для удобства можно сохранить внесенные изменения в виде отдельного linker-файла link_OTP.ld и создать новую конфигурацию сборки - Debug_OTP. В результате повторной компиляции проекта в папке Debug_OTP появится файл в формате hex, который далее можно использовать для прошивки OTP загрузочной программой. Полученная в результате программа хранит все постоянные данные в области памяти REGION_LOAD, которая является областью памяти BOOT_OTP, с которой стартует загрузочная программа при подаче питания.


3. Программирование чистой OTP-памяти загрузочной программой

После получения hex-файла с загрузочной программой необходимо сгенерировать массив данных, который далее можно использовать в программе-загрузчике (в архиве в конце статьи это проект Loader) - которая будет программировать OTP-память загрузочной программой. Проект Loader реализует программирование памяти OTP массивом данных, полученным в результате разработки и компиляции проекта загрузочной программы Bootloader

Для генерации массива данных можно воспользоваться сторонними утилитами, например, srec_cat, которая позволяет получить из hex-файла массив байтов (в качестве типа выходного файла следует выбрать -C-Array с опцией -C_COMpressed). Кроме того, в конце этого файла генерируется информация о каждом сегменте данных: начальный адрес, конечный адрес и размер. Полученную информацию далее можно использовать в программе-загрузчике. Следует обратить внимание на начальный адрес: он должен равняться началу OTP-памяти 0x0002_0000.

Утилита srec_cat добавлена в проект загрузочной программы Bootloader. Данная утилита запускается при сборке конфигурации Debug_OTP с помощью скрипта post-build.bat, который расположен в корне проекта Bootloader. По завершении работы утилита srec_cat создает в папке Debug_OTP файл BootloaderCode.h с массивом данных и дополнительной информацией о сегментах. Файл BootloaderCode.h нужно скопировать в проект Loader, в папку src.

Программирование массивом данных осуществляется по описанному выше алгоритму.

Проект Loader реализует минимальный необходимый функционал, а именно:

  1. Настройка тактовой частоты от внешнего резонатора HSE = 8 МГц.

  2. Конфигурация контроллера OTP.

  3. Программирование памяти указанным массивом по сегментам.

  4. Верификация записанных данных по сегментам.

На основе этого базового алгоритма может быть реализован дополнительный функционал, например, предварительная проверка наличия данных по адресам, по которым будет записываться массив. 

Использование внешнего источника частоты HSE необходимо для обеспечения точного времени пауз для контроллера OTP. При использовании резонатора HSE с частотой, отличной от 8 МГц, или при использовании генератора необходимо внести соответствующие изменения. Верификация записанных данных также является необходимым этапом, так как OTP-память имеет такой параметр, как коэффициент программируемости.

Проект Loader в архиве содержит актуальный файл BootloaderCode.h   

Запуск проекта Loader из памяти Flash может повлиять на последующие запуски, т.к. программа останется во Flash-памяти после снятия питания, поэтому рекомендуется запускать данный проект из ОЗУ.
Сохранить статью в PDF

Документация

Программное обеспечение

Теги

Была ли статья полезной?