======Запуск МК 1986ВЕ8Т и 1923ВК014 с внешней памяти по SPI===== В МК 1986ВЕ8(1)Т и 1923ВК014 предусмотрен режим старта с внешней памяти по интерфейсу SPI. В данном режиме МК по SPI загружает программу из внешней памяти во внутреннюю память ОЗУ, после чего осуществляет её запуск. При выборе соответствующего режима запуска МК в bootloder’e запускается загрузчик, который выполняет загрузку и выполнение программы по определённым требованиям, заданным в специальном заголовке. В данной статье мы подробно рассмотрим, как осуществляется загрузка программы из внешней памяти, и как сформировать образ программы со специальным информационным заголовком. =====Описание режима запуска с внешней памяти по SPI===== Согласно спецификации на МК, режимы запуска с внешней памяти по SPI обозначаются как SPI0,1 и SPI2,3. Первый режим SPI0,1 предназначен для работы с внешней памятью типа 5576, предназначенной для конфигурирования ПЛИС, второй режим SPI2,3 используется для работы с обычными микросхемами памяти по интерфейсу SPI фирмы Motorola в режиме SPO = 0, SPH = 0. Считывание данных из SPI памяти в режиме SPI2,3 начинается с помощью команды Read array (0x03) по адресу 0x000000. Алгоритм загрузчика по SPI приведен в bootloader'e МК 1986ВЕ8Т (функция runAppSPI), который доступен на [[http://forum.milandr.ru/viewtopic.php?f=47&t=2569&p=22622&hilit=%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D1%87%D0%B8%D0%BA#p22623|форуме Миландр]]. Подробная информация про параметры обмена по SPI описана в спецификации, в разделе «Режимы работы микроконтроллера». Для определения параметров загрузки и запуска программы в начало образа необходимо добавить информационный заголовок. Для режимов SPI0,1 и SPI2,3 информационные заголовки имеют немного различный формат, а именно, для SPI0,1 информационный заголовок начинается с параметра SDRAM_ADDR, а для SPI2,3 – со смещения информационного заголовка OFFS. **В данной статье мы рассмотрим случай формирования информационного заголовка только для режима SPI2,3.** При старте МК в режиме SPI2,3 загрузчик сначала считывает информационный заголовок, по которому определяет основные параметры загрузки (куда и сколько загрузить) и выполнения (откуда выполнить старт), а затем уже загружает основную программу. Подробная структура и параметры информационного заголовка для режима SPI2,3 представлены на рисунке ниже: слева представлен информационный заголовок с OFFS = 0x00000000, справа - с OFFS не равным 0x00000000 {{prog:start_spi:inform_head.png?750}} В информационный заголовок входят следующие параметры: * SRAM_ADDR – 32-х разрядный адрес, по которому будет расположен образ копируемой программы во внутренней памяти ОЗУ. Определяет, куда загрузить программу. В МК 1986ВЕ81Т внутренняя память представлена двумя ОЗУ: 128 Кбайт (эмуляция OTP) и 32 Кбайт. Загрузка по SPI может быть осуществлена только в ОЗУ 32 Кбайт. Запись в ОЗУ 128 Кбайт выполняется с помощью регистрового доступа, поэтому для загрузки программы по SPI в ОЗУ 128 Кбайт необходимо реализовать отдельный загрузчик. * START ADDR – 32-х разрядный адрес, которому будет передано управление после копирования программы. Обычно программа стартует с обработчика ResetHandler, адрес которого указывается в таблице векторов прерываний по адресу 0x04. * PROG_LEN – 32-х разрядный размер образа программы в словах (32 бит) без учета CRC16, определяющий количество данных, которые необходимо загрузить. * CRC_CNT – 16-ти разрядная длина данных в словах, по которым вычисляется значение crc16 в образе программы. Подробнее данный параметр разберём ниже. * CRC16 – значение контрольной суммы crc16, которое рассчитывается по следующим параметрам информационного заголовка: OFFS, SRAM_ADDR, START_ADDR, PROG_LEN, CRC_CNT. * OFFS – 32-разрядный адрес смещения информационного заголовка. Значение OFFS всегда расположено с 0-го адреса памяти. Выбирая OFFS, при необходимости, можно сдвинуть информационный заголовок и образ программы в любое место внешней памяти. Рассмотрим подробнее параметры CRC16 и CRC_CNT. CRC (циклически избыточный код) – это алгоритм нахождения контрольной суммы, предназначенный для проверки целостности данных. Число 16 в обозначении СRC указывает на степень порождающего полинома и определяет количество битов, используемых для вычисления CRC. Подробнее про CRC описано в статье [[https://startmilandr.ru/doku.php/prog:spec:crccode|Начальные сведения о вычислении контрольной суммы CRC]], также алгоритм вычисления crc16 приведён в спецификации, поэтому не будем на этом останавливаться. Главное назначение crc16 - это верификация данных, по которым было рассчитано crc16. Верификация производится путём сравнения считанного значения crc16 и рассчитанного МК crc16. Если считанное и рассчитанное значения crc16 не совпадают, значит, при чтении произошла ошибка, поэтому МК инициирует программный сброс, чтобы начать процесс чтения заново. По значению параметра CRC16 проводится проверка ошибок в информационном заголовке. При необходимости, можно добавить проверку по алгоритму CRC не только для информационного заголовка, но и для образа программы. Для этого служит параметр CRC_CNT. Если параметр CRC_CNT задан, то образ программы разбивается на блоки по CRC_CNT слов, при этом для каждого блока считается отдельное значение crc16. {{prog:start_spi:crc_cnt.png?450}} Разберём немного подробнее. Например, выбрав CRC_CNT=5, весь образ программы разбивается на блоки по 5 слов, причём для каждого такого блока должно быть рассчитано crc16. Уникальное для каждого блока значение crc16 располагается после данных блока. Необходимо учесть, что если последний блок окажется меньше, чем CRC_CNT, то для данного блока проверка CRC выполняться не будет. Таким образом, для основной программы расчёт CRC либо не выполняется совсем (CRC_CNT = 0), либо выполняется для N блоков по CRC_CNT, при этом N*CRC_CNT ≤ PROG_LEN. =====Утилита для создания образа ПЗУ ===== Утилиту LSPI и её исходные файлы можно скачать [[https://drive.google.com/uc?authuser=0&id=1ilbzp4pdpUuTkhTHP_crP7W26IMPewyS&export=download|здесь]]. Утилита «LSPI.exe» формирует загрузочный образ ПЗУ для старта МК в режиме SPI2,3. Она работает только в консольном режиме и не имеет графической оболочки. {{prog:start_spi:lspi.png}} Работа с утилитой осуществляется из командной строки, формат ввода команд имеет следующий вид: LSPI [Опции] <Входной HEX-файл> <Выходной HEX-файл> На вход утилиты принимается образ программы в формате Intel HEX, который может быть получен, например, после компиляции в среде Keil или IAR. На выходе получаем образ ПЗУ также в формате Intel HEX, которой состоит из информационного заголовка, образа программы и рассчитанных значений crc16. По умолчанию все параметры информационного заголовка задаются автоматически, а именно: * значение OFFS = 0x00000000; * значение SDRAM_ADDR считывается из образа программы. В среде Keil данный параметр указывается в опциях проекта, поле IROM. Текущая версия утилиты поддерживает работу только с одной областью памяти программ. При выборе нескольких областей памяти программ, корректная работа не гарантируется. Например, в Keil должна быть выбрана только одна область IROM. {{prog:start_spi:keil_options_irom.png}} * значение START_ADDR также считывается из образа программы и содержит адрес вектора ResetHandler. При обычном запуске МК всегда начинает выполнение программы именно с обработчика ResetHandler; * значение PROG_LEN рассчитывается автоматически; * значение CRC_CNT = 0x0000, т.е. расчёт crc16 для образа программы не происходит; * значение CRC16 также рассчитывается автоматически. Если необходимо установить параметры информационного заголовка, отличающиеся от значений по умолчанию, то можно использовать специальные опции. Каждая опция имеет формат длинной опции и начинается с двух тире «--». Полный список опций и формат их использования приведён в хэлпе утилиты: LSPI --help Например, чтобы разбить программу на N блоков по 20 слов с рассчитанными значениями crc16, необходимо указать значение параметра CRC_CNT = 20: LSPI --CRC_CNT 20 In.hex Out.hex ====Особенность формирования образа ПЗУ для МК 1923ВК014==== Необходимо отметить, что в МК 1923ВК014 область памяти программ RAMC после старта имеет адрес 0x0200_0000. Однако, после выполнения бутовой программы происходит ремаппинг памяти, и область RAMC оказывается по адресам 0x0000_0000. Таким образом, сборка программы должна быть осуществлена для адресов, начиная с 0x0000_0000 (в Keil поле IROM). {{prog:start_spi:1923bk014.png}} Однако загрузку программы необходимо производить в память ОЗУ, начиная с адреса 0x0200_0000. Для этого необходимо использовать опцию --SDRAM_ADDR: LSPI --SDRAM_ADDR 0x02000000 In.hex Out.hex Необходимость ремаппинга памяти в 1923ВК014 связана с тем, что в ядре Cortex M0 таблица векторов прерываний жёстко привязана к 0 адресу, поэтому сначала при старте МК по 0 адресу располагается бутовая программа, а после ремаппинга по 0 адресу уже оказывается пользовательская программа. ===== Загрузка образа ПЗУ во Flash память ===== Для запуска с внешней памяти по интерфейсу SPI на отладочной плате для 1923ВК014 предусмотрена микросхема ПЗУ 1636РР3У. {{prog:start_spi:1923bk014_flash.png}} На отладочной плате для 1986ВЕ8Т также возможен запуск в режиме SPI2,3, но для этого в разъём XP23 должен быть установлен модуль Flash память на основе 1636РР3(4)У. {{prog:start_spi:1986be8_flash.png}} Для программирования микросхем серии 1636РР можно использовать [[https://ic.milandr.ru/products/programmno_otladochnye_sredstva/programmatory/vnutriskhemnyy_usb_programmator_dlya_mikroskhem_flash_pamyati_serii_1636rr/|внутрисхемный USB-программатор]], чем мы и воспользуемся. В качестве ПО для программатора поставляется программа [[https://ic.milandr.ru/soft/ | ProgFlash]]. Запуск программы необходимо осуществлять обязательно от имени администратора, иначе программатор может не определиться. {{prog:start_spi:progflash.png}} Перед программировании 1636РР3У на доработанной отладочной плате для МК 1923ВК014 (снизу платы разведён внешний провод) необходимо снять перемычку SPI SEL, подключить программатор к ПК, запустить программу ProgFlash, подключить программатор к плате, выставить напряжение питания на плате 3,3 В, после чего включить питание. Перед программированием Flash памяти, установленной на модуле, перемычку SPI select необходимо снять, а сам модуль извлечь из мезонинного разъёма отладочной платы для 1986ВЕ8Т.