Этот документ (перевод руководства [1]) описывает функции и работу встроенного в микроконтроллер (MCU) STM8 загрузчика STSW-STM8068 (bootloader). Этот код находится в постоянной системной памяти MCU (ROM) и позволяет записать области встроенной памяти, включая память программ Flash, EEPROM данных и RAM. Записываемые данные передаются в MCU через набор стандартных последовательных интерфейсов LINUART/UART/USART, SPI и CAN. Код загрузчика почти одинаковый для всех версий STM8. Однако поддержка тех или иных интерфейсов в зависимости от модели MCU может меняться (например, для 128-килобайтных устройств SPI не поддерживается).
Следует отметить, что альтернативным решением для внутрисхемного программирования может также служить интерфейс отладчика SWIM, который осуществляет обмен данными только по одному проводу [3].
После сброса загрузчик проверяет, является ли память программ чистой, или установлен ли определенный байт опций, позволяющий изменять код. Если условия запуска загрузчика не выполняются, то загрузчик запускает код приложения пользователя, иначе загрузчик берет управление на себя и ждет загрузки программы.
Когда загрузчик активируется, выполняются следующие основные задачи:
• Опрашиваются все поддерживаемые последовательные интерфейсы, чтобы определить, какой интерфейс будет использоваться для загрузки (набор поддерживаемых интерфейсов зависит от модели MCU, см. таблицу 1). • Программируется код, данные, байты опций и/или таблицы векторов по указанным адресам. Эти данные поступают от хоста программирования (обычно это компьютер, на котором запущена утилита DFU [2]).
В каждом MCU STM8 встроен специфичный код загрузчика, который является общим для целой группы устройств STM8. Соответствие между группами STM8 и моделями STM8 приведено в таблице 1. Все упомянутые группы используются в описании этого руководства.
В таблице 2 приведен список устройств STM8 без встроенного загрузчика (внутри кристалла MCU нет ROM bootloader). При использовании этих устройств пользователь должен написать свой собственный загрузчик и сохранить его в области программ UBC program area (см. руководства по сериям STM8S, STM8AF, STM8L, STM8AL и STM8T для получения информации об области памяти UBC).
Таблица 2. Группы STM8 без поддержки загрузчика.
Группа STM8
Модели MCU
STM8AF и STM8S Series low density
STM8AF621x/2x, STM8Sx03xx, STM8S001xx
STM8L101 line low density
STM8L101xx, STM8L001xx
STM8T Series ultra low-power
STM8TL5xxx
[Активация загрузчика]
Аппаратный вектор сброса STM8 находится в начале boot ROM (0x006000), в то время как другие вектора прерываний находятся в памяти Flash, начиная с адреса 0x008004.
MCU запускает boot ROM (делает безусловный переход в область boot ROM), и после проверки ячеек памяти по определенным адресам (см. далее таблицу 4 "Первоначальные проверки загрузчика"), будет либо активирован загрузчик, либо будет запущен код пользователя, определенный вектором сброса (0x008000).
Алгоритм активации загрузчика описан на рис. 1. В предыдущих версиях загрузчика производился возврат в состояние "wait for SYNCH" ("ожидание синхронизации", см. пунктирную линию перехода на рис. 1), когда тест на чистоту памяти Flash ("Flash virgin") был положительный. В более новых версиях это было заменено на программным (software reset, SW reset) сбросом, чтобы предотвратить вход firmware пользователя в бесконечный цикл (например, из-за электромагнитных помех). Эта модификация загрузчика в таблице 15 называется "Защита от блокировки EMC". В таблице 3 перечислены версии загрузчика, в которых пунктирная линия заменена на SW reset.
Номер версии загрузчика вычитывается командой Get (см. далее описание команды Get в соответствующей врезке). Версия загрузчика представлена двумя цифрами BCD (с десятичной точкой между двумя цифрами), закодированными в одном байте, который выдается как результат команды Get. Например, байт версии 0x21 обозначает bootloader version 2.1.
Таблица 3. Версии загрузчика, для которых верен алгоритм активации на рис. 1.
Группа STM8
Bootloader version
STM8AF и STM8S Series high density
v2.2
STM8AF и STM8S Series medium density
v1.3
STM8L и STM8AL Series high/medium+ density
v1.0
STM8L и STM8AL Series medium density
v1.2
STM8L Series low density
v1.0
Рис. 1. Алгоритм активации загрузчика.
Примечания:
(1) См. далее описание алгоритма загрузчика, где объясняются места алгоритма от 1 до 8. (2) См. таблицу 4 "Первоначальные проверки загрузчика". (3) Подпрограммы, окруженные линией из точек, загружаются хостом в RAM. Они удаляются командой GO перед прыжком в память программ Flash для запуски приложения пользователя. (4) Чистота памяти Flash проверяется анализом содержимого по адресу 0x8000. Если [0x8000] == 0x82 или 0xAC, то память Flash не чистая.
[Алгоритм загрузчика]
Здесь приведено описание шагов алгоритма загрузчика на рис. 1:
1. Запрещаются все источники прерываний.
2. MCU может запустить процесс загрузчика с помощью проверок, показанных в таблице 4 - в соответствии с содержимым первой ячейки памяти программ Flash (0x008000) и байт опций, разрешающих работу загрузчика ("bootloader enable" option bytes). MCU проверяет следующие условия запуска загрузчика (этот процесс проверки суммарно перечислен в таблице 4):
Условие 1: MCU проверяет, пуста ли память устройства путем анализа содержимого по адресу 0x008000 (вектор сброса). Если байт по этому адресу не равен 0x82 или 0xAC, то определяется, что устройство чистое, и загрузчик остается в активном состоянии и ждет команд от хоста без таймаутов.
Условие 2: MCU проверяет, установлены ли байты опций (2 байта) для разрешения работы загрузчика, или нет. Загрузчик разрешается значением 0x55AA, и запрещается для всех других значений (где размещаются эти байты в памяти, см. даташит на используемый MCU). Если в этих байтах опций 0x55AA, то загрузчик остается активным и ждет команд от хоста, пока не истечет таймаут в 1 секунду. Если в течение этого времени хост не передал команду, то загрузчик делает прыжок по вектору приложения пользователя (jump 0x008000).
Условие 3: если байты опций запретили загрузчик (там находится значение, отличающееся от 0x55AA), то загрузчик делает прыжок по вектору приложения пользователя (jump 0x008000).
3. Когда защита от чтения (ROP) активна, то чтение памяти программ Flash запрещено. В этом случае загрузчик останавливается и запускается программа пользователя. Если ROP неактивна, то загрузчик продолжает свое выполнение (см. "Приложение A. Как обновить MCU, у которого активна защита ROP").
4. Периферийное устройство CAN можно использовать только если присутствует определенная тактовая частота, заданная снаружи (8 МГц, 16 МГц или 24 МГц). CAN инициализируется на скорости 125 кбит/сек. Интерфейсам UART и SPI не требуется наличие внешнего тактирования. Нужно подождать 6 мс, чтобы стала стабильной частота кварцевого генератора HSE.
5. Запускается внутренний высокоскоростной генератор RC (HSI) на частоте 16 МГц, и инициализируются ножки приемника UART в режиме входа с верхними подтягивающими резисторами (pull-up) путем настройки регистров GPIO. SPI инициируется в подчиненном режиме (slave mode). Затем происходит ожидание 4 мс, чтобы застабилизировались уровни ножках интерфейсов. Рекомендуется, чтобы хост подождал 10 мс от момента сброса MCU перед отправкой байта/сообщения SYNCH. Это время требуется для инициализации загрузчика.
6. Опрашиваются интерфейсы: все периферийные устройства проверяются загрузчиком в ожидании байта/сообщения синхронизации (SYNCH = 0x7F) в течение таймаута в 1 секунду. Если истек таймаут и память программ Flash чистая, то загрузчик остается активным, в бесконечном цикле ожидая поступления команд от хоста через программный сброс. Если после истечения таймаута память программ Flash не чистая, то загрузчик восстанавливает значения регистров в состоянием по умолчанию, и делает прыжок на вектор сброса (находится по адресу 0x008000). Для версий загрузчика, перечисленных в таблице 3, SW reset генерируется после истечения таймаута в том случае, если память программ пустая (потому что безопаснее оставаться в бесконечном цикле, если присутствует аппаратная ошибка микросхемы).
Примечание: при ошибке синхронизации (загрузчик принял байт/сообщение, отличающийся от SYNCH = 0x7F), в соответствии с периферийным устройством можно различать 2 разные ситуации. В случае UART необходим сброс MCU перед тем, как может произойти повторная синхронизация (см. "Приложение E. Ограничения загрузчика UART"). В случае CAN или SPI может быть продолжен опрос интерфейсов, пока не произойдет синхронизация или не истечет таймаут.
7. Если UART-ы приняли сообщение синхронизации, то загрузчик по нему автоматически определит скорость интерфейса, инициализирует UART и перейдет к шагу 8. Если сообщение синхронизации поступило через CAN или SPI, то загрузчик сразу переходит к шагу 8.
Примечание: как только один из доступных интерфейсов принял сообщение синхронизации, все другие интерфейсы запрещаются.
8. Ожидание команд: команды проверяются и выполняются в бесконечном цикле. Чтобы выйти из загрузчика, хост должен послать команду GO. После получения команды GO загрузчик удаляет подпрограммы EM и WM из RAM и делает прыжок на адрес, выбранный хостом.
Примечание: чтобы можно было записать/стереть данные во Flash и EEPROM, хост должен сначала записать в RAM специальные подпрограммы для записи и стирания. Эти подпрограммы (файлы на языке ассемблера *.s19) предоставляются вместе с загрузчиком. Хост должен выгрузить эти подпрограммы по адресу 0x0000A0. См. далее секцию "Подпрограммы erase/write в памяти RAM".
Таблица 4. Первоначальные проверки загрузчика.
Порядок проверки
Проверяемое условие
Реальное состояние памяти программ Flash -> следующее действие
1 проверка
[0x008000] < > (0x82 или 0xAC)
Память программ чиста. Загрузчик продолжает работу.
2 проверка
[BL_OPT] == 0x55AA(1)
Память программ уже была записана, работа загрузчика разрешена байтами опций BL_OPT. Загрузчик продолжает работу.
3 проверка
ROP активна
Память MCU защищена от чтения -> переход по вектору сброса в память программ Flash (запуск прикладной программы).
Примечания:
(1) См. даташит на используемый MCU для места размещения [BL_OPT] байта опций на карте памяти. (2) После инициализации интерфейса проверяется бит ROP, чтобы не допустить неавторизованное чтение памяти программ Flash и EEPROM данных.
[Настройки периферийных устройств]
В этой секции описываются аппаратные настройки коммуникационных интерфейсов STM8:
• UARTs/LINUART • SPI • CAN
Примечание: во время загрузки (когда загрузчик по процедуре синхронизации определил интерфейс и начал работу с ним) используется только один коммуникационный интерфейс, все остальные запрещаются.
Таблица 5. Последовательные интерфейсы, связанные с MCU STM8(1).
Группа STM8
Последовательный интерфейс
STM8AF Series - high density
USART, LINUART (в режиме "reply"), CAN
STM8AF Series - medium density
LINUART (в режиме "reply"), SPI
STM8S Series - high density
UART1, UART3 (в режиме "reply"), CAN
STM8S Series - medium density
UART2 (в режиме "reply"), SPI
STM8L Series - low density
UART, SPI
STM8L и STM8AL Series - medium density
UART
STM8L и STM8AL Series high/medium+ density
UART1, UART2, UART3 (в режиме "reply"), SPI1, SPI2
Примечание (1): таблица выше отражает только текущие версии загрузчиков и состояния устройств.
USART/UART. Это периферийное устройство поддерживает последовательный асинхронный обмен. Настройки USART/UART:
• Кадр данных: 1 старт-бит, 8 бит данных, 1 бит четности настроен н четность данных, 1 стоп-бит. • Скорость: baud rate детектируется автоматически загрузчиком по команде синхронизации. Когда хост посылает байт синхронизации 0x7F, загрузчик анализирует длительности его уровней и по ним настраивает скорость USART/UART, чтобы она совпадала со скоростью хоста. Максимальная baud rate = 1 Mbps (115200 baud для STM8L/AL-high/medium+ density), минимальная baud rate = 4800 bps.
Чтобы работало автоматическое определение скорости, на плате приложения должна обеспечиваться стабильность сигнала RxD (загрузчик разрешает внутренний pull-up на ножке RxD).
Настройки выводов:
• Когда загрузчик ожидает байта синхронизации (SYNCH = 0x7F), ножки RxD настраиваются в режим ввода с верхним подтягивающим резистором (pull-up). • Если загрузчик активируется с интерфейсом USART/UART, то ножки TxD настраиваются в режиме двухтактного выхода (push-pull). • Если загрузчик не активируется (за таймаута в 1 секунду не был принят байт SYNCH), то все ножки USART/UART устанавливается в состояние по умолчанию после сброса. • Если загрузчик активировался на другой интерфейс (отличающийся от USART/UART), то ножки RxD остаются в режиме ввода с верхней подтяжкой (internal pull-up).
LINUART/UART в режиме "Reply". Настройки:
• Кадр данных: 1 старт-бит, 8 бит данных, без бита четности, 1 стоп-бит. • Скорость: baud rate детектируется автоматически загрузчиком по команде синхронизации. Когда хост посылает байт синхронизации 0x7F, загрузчик анализирует длительности его уровней и по ним настраивает скорость USART/UART, чтобы она совпадала со скоростью хоста. Максимальная baud rate = 550 kbps (115200 baud для STM8L/AL-high/medium+ density), минимальная baud rate = 4800 bps.
Чтобы работало автоматическое определение скорости, на плате приложения должна обеспечиваться стабильность сигнала RxD (загрузчик разрешает внутренний pull-up на ножке RxD).
Режим Reply. Хост должен отвечать на все байты, которые посланы из загрузчика. Если сигналы TxD и RxD используют один и тот же физический вывод (например, обмен 1-wire), то ответы от хоста не обязательны, поскольку выводы RxD и TxD совпадают.
Настройки выводов:
• Когда загрузчик ожидает байта синхронизации (SYNCH = 0x7F), ножки RxD настраиваются в режим ввода с верхним подтягивающим резистором (pull-up). • Если загрузчик активируется с интерфейсом LINUART/UART, то ножки TxD настраиваются в режиме двухтактного выхода (push-pull). • Если загрузчик не активируется (за таймаут в 1 секунду не был принят байт SYNCH), то все ножки LINUART/UART устанавливается в состояние по умолчанию после сброса. • Если загрузчик активировался на другой интерфейс (отличающийся от LINUART/UART), то ножки RxD остаются в режиме ввода с верхней подтяжкой (internal pull-up).
SPI. Настройки для SPI следующие:
• 8 бит данных, MSB идет первым. • Скорость определяется частотой сигнала тактов хоста, поскольку он работает как мастер шины. • Периферийное устройство SPI настраивается в режиме подчинения (slave mode) с программной обработкой NSS. • Полярность данных: CPOL = 0 (в состоянии ожидания уровень SCK лог. 0), CPHA = 0 (первый перепад тактов служит для захвата уровня данных).
Перед отправкой байта хост должен выдержать задержку 6 мкс.
Периферийное устройство SPI доступно через выводы SPI_SCK, SPI_MOSI и SPI_MISO со следующими настройками:
• Когда загрузчик ждет байта синхронизации (SYNCH = 0x7F) ножки SPI_MISO настроены в режиме двухтактного выхода (push-pull). • Если загрузчик не активирован (не был получен байт SYNCH за таймаут в 1 секунду), то все ножки SPI_MISO настраиваются в состояние по умолчанию после сброса. • Если загрузчик активировался на другом интерфейса (не SPI), то ножки SPI_MISO остаются в режиме двухтактного выхода (push-pull).
CAN. Чтобы адресовать устройства, подключенные к одной и той же шине, протокол CAN предоставляет в своем кадре поле стандартного идентификатора (Standard ID 11 бит) и опциональное поле расширенного идентификатора (extended ID 18 бит). Рис. 2 показывает кадр CAN, который использует только стандартный идентификатор.
Рис. 2. Фрейм CAN.
Настройки CAN следующие:
• Идентификатор Standard (не Extended). • Скорость следования бит.
По умолчанию установлена скорость 125 килобит/сек. Эта скорость может быть изменена во время работы загрузчика командой speed, чем может быть достигнута скорость до 1 Mbit/сек.
Настройки передачи (от STM8 к хосту):
• Tx mailbox0: разрешен. • Tx mailbox1 и Tx mailbox2: запрещен. • Tx ID: 0x02. • Исходящие сообщения содержат 1 байт данных.
Настройки приема (от хоста к STM8):
• Байт синхронизации 0x7F находится в ID RX, а не в поле данных пакета. • ID RX зависит от команды (0x00, 0x03, 0x11, 0x21, 0x31, 0x43). • Проверка на ошибку: если поле ошибки (биты [6:4] в регистре CESR) отличаются от 000b, то сообщение отбрасывается, и хосту отправляется NACK. • В случае переполнения FIFO (overrun condition) сообщение отбрасывается, и хосту отправляется NACK.
Приходящие сообщения могут содержать от 1 до 8 байт данных.
Периферийное устройство CAN доступно через ножки CAN_TX и CAN_RX, со следующими настройками:
• Когда загрузчик ждет байта синхронизации в идентификаторе фрейма CAN (SYNCH = 0x7F), ножка CAN_TX настроена в режиме двухтактного выхода (push-pull). • Если загрузчик не активировался (за таймаут в 1 секунду не было байта SYNCH), то ножка CAN_TX настраивается в состояние по умолчанию после сброса. • Если загрузчик активировался на другой интерфейс (не CAN), то ножка CAN_TX остается в режиме двухтактного выхода (push-pull).
[Команды загрузчика]
Команды, поддерживаемые загрузчиком, перечислены в таблице 6.
Таблица 6. Команды загрузчика.
Команда
Код команды
Описание команды
Get
0x00
Получение версии и списка допустимых команд, поддерживаемых текущей версией загрузчика.
Read Memory
0x11
Чтение до 256 байт памяти, начиная с адреса, указанного хостом.
Erase Memory
0x43
Стирает один сектор или все секторы памяти программ Flash / data EEPROM.
Write Memory
0x31
Записывает до 128 байт в RAM или память программ Flash / data EEPROM, начиная с адреса, указанного хостом.
Speed
0x03
Позволяет поменять скорость CAN во время работы загрузчика.
Go
0x21
Делает безусловный переход по адресу, указанному хостом, чтобы запустить загруженный код.
Таблица 7. Коды загрузчика.
Мнемоника
Код
Описание
SYNCH
0x7F
Байт синхронизации.
ACK
0x79
Acknowledge, положительное подтверждение.
NACK
0x1F
No acknowledge, отрицательного подтверждение.
Token
0xXX
Любой байт, который хост посылает в загрузчик через интерфейс SPI, чтобы принять ответ от загрузчика (требуется передать данные через SPI, когда нужно принять данные, это связано с особенностью работы SPI для генерации тактов). Обычно для значения токена используется 0x00.
BUSY
0xAA
Состояние флага занятости.
Когда загрузчик принимает команды через UART, CAN или SPI, общий протокол следующий:
1. Загрузчик посылает байт ACK (0x79) хосту и ждет адрес адрес и байт контрольной суммы, которые проверяются при получении.
2. Когда адрес правильный и контрольная сумма в порядке, загрузчик посылает байт ACK (0x79), иначе посылает байт NACK (0x1F) и обрывает выполнение команды. Загрузчик ждет определенное количество передаваемых байт (N байт) и байт контрольной суммы.
– Если контрольная сумма в порядке, то загрузчик выполняет команду, начиная с принятого адреса. – Если контрольная сумма не в порядке, то загрузчик посылает сначала NACK, и обрывает выполнение принятой команды.
Протоколы загрузчика через UART и SPI идентичен внутри MCU, но отличаются со стороны хоста. Нужен байт токена, когда через SPI отправляется каждый байт (см. рисунки 5, 11, 17, 23 и 31).
Протокол загрузчика CAN отличается от всех других протоколов.
Ниже во врезках описываются команды загрузчика для разных протоколов.
Команда Get позволяет хосту получить версию загрузчика и поддерживаемые им команды. Когда загрузчик принимает команду Get, он передаст хосту свою версию и коды поддерживаемых команд.
[USART/LINUART/UART1/UART2/UART3]
Рис. 3. Команда Get через USART/LINUART/UART1/UART2/UART3 на стороне хоста.
Байт 1: ACK. Байт 2: N = 5 = количество отправляемых байт -1 (1 ≤ N+1 ≤ 256). Байт 3: версия загрузчика (0 < version ≤ 255). Байт 4: 0x00 - команда Get. Байт 5: 0x11 - команда Read Memory. Байт 6: 0x21 - команда Go. Байт 7: 0x31 - команда Write Memory. Байт 8: 0x43 - команда Erase Memory. Байт 9: ACK.
[CAN]
Рис. 7. Команда Get через CAN на стороне хоста.
Хост посылает сообщения следующим образом.
Сообщение команды: Std ID = 0x00, код длины данных (DLC) = не имеет значения.
Рис. 8. Команда Get через CAN на стороне MCU.
STM8 посылает сообщения следующим образом.
Сообщение 1: Std ID = 0x02, DLC = 1, data = ACK. Сообщение 2: Std ID = 0x02, DLC = 1, data = N = 6 = количество посылаемых байт -1 (1 ≤ N+1 ≤ 256). Сообщение 3: Std ID = 0x02, DLC = 1, data = версия загрузчика (0 < version ≤ 255). Сообщение 4: Std ID = 0x02, DLC = 1, data = 0x00 - команда Get. Сообщение 5: Std ID = 0x02, DLC = 1, data = 0x03 - команда Speed. Сообщение 6: Std ID = 0x02, DLC = 1, data = 0x11 - команда Read Memory. Сообщение 7: Std ID = 0x02, DLC = 1, data = 0x21 - команда Go. Сообщение 8: Std ID = 0x02, DLC = 1, data = 0x31 - команда Write Memory. Сообщение 9: Std ID = 0x02, DLC = 1, data = 0x43 - команда Erase Memory. Сообщение 10: Std ID = 0x02, DLC = 1, data = ACK.
Команда читает память (RAM, память программ Flash, данные EEPROM или регистры). Когда загрузчик получает команду Read Memory, он передает необходимые данные ((N + 1) байт) хосту, начиная с указанного в команде адреса.
Примечание: допустимыми считаются адреса RAM, памяти программ Flash, EEPROM данных и адреса регистров (см. даташит на используемый MCU). Если загрузчик принял недопустимый адрес, то произойдет ошибка (см. таблицу 10).
[USART/LINUART/UART1/UART2/UART3]
Рис. 9. Команда Read Memory через USART/LINUART/UART1/UART2/UART3 на стороне хоста.
Хост посылает байты в STM8 следующим образом:
Байты 1-2: 0x11+0xEE (команда и её комплемент). Байты 3-6: начальный адрес (адрес 32-битный). Байт 3 = MSB. Байт 6 = LSB. Байт 7: контрольная сумма = XOR (байт 3, байт 4, байт 5, байт 6). Байт 8: количество байт для чтения -1 (0 ≤ N ≤ 255). Байт 9: контрольная сумма (комплемент байта 8).
Рис. 10. Команда Read Memory через USART/LINUART/UART1/UART2/UART3 на стороне MCU.
[SPI]
Рис. 11. Команда Read Memory через SPI на стороне хоста.
Хост посылает байты в STM8 следующим образом:
Байт 1: 0x11 - Command ID. Байт 2: 0xEE - комплемент команды. Байт 3 (token): 0xXY; хост ждет ACK или NACK от MCU. Байты 4-7: начальный адрес (32-битный адрес). Байт 4 = MSB. Байт 7 = LSB. Байт 8: контрольная сумма = XOR (байт 4, байт 5, байт 6, байт 7). Байт 9 (token): 0xXY; хост ждет ACK или NACK от MCU. Байт 10: количество байт для чтения -1 (0 ≤ N ≤ 255). Байт 11: контрольная сумма (комплемент байта 10). Байт 12 (token): 0xXY; хост ждет 1-й байт данных. Байт 12+N (token): 0xXY; хост ждет N+1-й байт данных.
Рис. 12. Команда Read memory через SPI на стороне MCU.
[CAN]
Сообщение CAN отправляется хостом следующим образом:
• ID содержит код команды (0x11). • Поле данных содержит адрес назначения (4 байта, байт 1 старший, и байт 4 младший байт адреса) и количество байт (N) для чтения.
Рис. 13. Команда Read Memory через CAN на стороне хоста.
Хост посылает сообщения команды следующим образом.
Std ID = 0x11, DLC = 0x05, data = MSB, 0xXX, 0xYY, LSB, N (где 0 < N ≤ 255).
Рис. 14. Команда Read Memory через CAN на стороне MCU.
STM8 отправляет сообщения следующим образом.
Сообщение ACK: Std ID = 0x02, DLC = 1, data = ACK. Сообщение данных 1: Std ID = 0x02, DLC = 1, data = 0xXX. Сообщение данных 2: Std ID = 0x02, DLC = 1, data = 0xXX. ... Сообщение данных (N+1): Std ID = 0x02, DLC = 1, data = 0xXX.
Примечание: загрузчик посылает столько сообщений данных, сколько байт можно прочитать.
Команда позволяет хосту стереть сектора Flash памяти программ и data EEPROM.
Загрузчик получает сообщение команды стирания, когда ID содержит тип команды 0x43, и поле данных содержит сектора для очистки (см. таблицу 9 с кодами секторов STM8). С размером сектора 1 килобайт получается гранулярность команды стирания в 8 блоков (1 блок = 128 байт). Если хосту надо стереть только 1 байт, то может использоваться команда записи (запись 0x00).
Описание команды Erase Memory:
1. Загрузчик принимает 1 байт, который содержит количество (N) стираемых секторов. N зависит от используемого MCU. 2. Затем загрузчик принимает (N + 1) байт, где каждый байт содержит код сектора (см. таблицу 9 с кодами секторов STM8).
Примечание: подпрограмма "стереть соответствующие сектора" выполняется в RAM. Таким образом, пользователь должен загрузить подпрограмму стирания в RAM перед отправкой команды стирания. Обратите внимание, что для некоторых версий загрузчика это не требуется (см. далее "Подпрограммы erase/write в памяти RAM").
Предупреждение: если хост отправит команду стирания, которая содержит некоторый корректный код сектора и один или большее количество запрещенных кодов сектора (см. таблицу 9 с кодами секторов STM8), то команда завершится неудачей, и ни один блок не будет стерт.
[USART/LINUART/UART1/UART2/UART3]
Рис. 15. Команда Erase Memory через USART/LINUART/UART1/2/3 на стороне хоста.
Примечания:
(1) "Total erase" стирает память программ и data EEPROM. Загрузчик сотрет всю память сектор за сектором. (2) Размер сектора 1 килобайт одинаковый для всех MCU STM8. Таким образом, гранулярность команды стирания составляет 8 блоков. Чтобы стереть 1 байт, может использоваться команда записи.
Хост посылает байты следующим образом.
Байт 1: 0x43 - Command ID. Байт 2: 0xBC - комплемент команде. Байт 3: 0xFF или количество стираемых секторов (0 ≤ N ≤ M); если N > M, в загрузчике произойдет ошибка cmd_error, после которой загрузчик примет N+1 байт данных и контрольную сумму (т. е. хост завершит команду).
Примечание: N зависит от используемого MCU. M = (размер памяти программ Flash в килобайтах) + (размер data EEPROM в килобайтах) -1.
Пример для STM8S Series-high density: M = 129, потому что размер памяти программ Flash 128 килобайт и data EEPROM 2 килобайта (128 + 2 - 1).
Пример для STM8S Series-medium density: M = 32, потому что память программ Flash 32 килобайта, и data EEPROM 1 килобайт (32 + 1 - 1).
Байт 4 или N+1 байт: 0x00 или (N+1 байт и затем контрольная сумма: XOR(N,[N+1 байт данных])).
Пример для STM8L и STM8AL Series-low density: M = 8, потому что память программ Flash 8 килобайт и data EEPROM (256 байт) в следующем начальном 1 килобайте (8 + 1 - 1).
Байт 4 или N+1 байт: 0x00 или (N+1 байт и затем контрольная сумма: XOR(N,[N+1 байт данных])).
Рис. 16. Команда Erase Memory через USART/LINUART/UART1/2/3 на стороне MCU.
[SPI]
Рис. 17. Команда Erase Memory через SPI на стороне хоста.
Примечание: когда используется команда стирания через SPI, необходимо подождать известный интервал времени (см. блок "Задержка" на рис. 17) перед отправкой последнего token-байта. Этот интервал задержки зависит от количества стираемых секторов (N). Delay = 30 * (N + 1)[мс], здесь 0 ≤ N ≤ 32. N = 32 в случае полной очистки (total erase). См. также "Приложение C. Опции тайминга SPI".
Хост посылает байты следующим образом.
Байт 1: 0x43 - Command ID. Байт 2: 0xBC - комплемент команде. Байт 3 (token): 0xXY; хост ждет ACK или NACK. Байт 4: 0xFF или количество стираемых секторов (0 ≤ N ≤ 32). Если N > 32, то произойдет ошибка cmd_error. Байт 5 или N+1 байт: 0x00 или (N+1) байт, и затем контрольная сумма: XOR(N,[N+1 байт данных]). Последний байт (token): 0xXY; хост ждет ACK или NACK.
Рис. 18. Команда Erase Memory через SPI на стороне MCU.
[CAN]
Рис. 19. Команда Erase Memory через CAN на стороне хоста.
Примечания:
(1) Загрузчик стирает память сектор за сектором. (2) Размер сектора 1 килобайт для всех MCU STM8. Таким образом, гранулярность команды erase составляет 8 блоков. Для стирания 1 байта может использоваться команда записи.
Хост посылает байты следующим образом.
Сообщение полного стирания: Std ID = 0x43, DLC = 0x01, data = 0xFF. Сообщение для посекторного стирания: Std ID = 0x43, DLC = от 0x01 до 0x08, data = см. таблицу 9: с кодами секторов STM8.
Рис. 20. Команда Erase Memory через CAN на стороне MCU.
Команда позволяет хосту записать данные в любое допустимое место на карте памяти (RAM, память программ Flash, data EEPROM или регистры) начиная с указанного адреса. Поступающие данные всегда записываются в RAM перед тем, как они загружаются в ячейки памяти, которые указал хост. Затем загрузчик проверяет, хочет ли хост записать данные в RAM, или же память программ Flash/data EEPROM.
Максимальный размер записываемого блока для STM8 равен 128 байтам данных. Чтобы записать данные в ячейки памяти Flash/EEPROM, загрузчик выполняет две разные операции записи:
1. WordWrite/FastWordWrite (запись слова / быстрая запись слова): записывает байт в память Flash/EEPROM. Это используется, когда количество отправляемых хостом байт меньше 128. В этом случае загрузчик выполняет операцию N раз. 2. BlockWrite (запись блока): записывает блок в память Flash/EEPROM. Это используется, когда количество отправляемых хостом байт (N) 128, и адрес равен числу, нацело делящемуся на 128. Другими словами, для использования этой операции отправляемый хостом блок должен быть выравнен на блок памяти. Если выравнивание не соблюдается, то будет использоваться байтовая операция записи (которая работает медленнее).
См. даташит на используемый MCU, чтобы использовать допустимый адрес. Если начальный адрес недопустимый, то произойдет ошибка add_error (см. таблицу 10).
Примечание: код команды записи принятых данных по указанному адресу выполняется в RAM. Таким образом, пользователь должен предварительно загрузить подпрограмму записи в RAM перед отправкой команды записи. Обратите внимание, что для некоторых загрузчиков это не требуется (см. далее секцию "Подпрограммы erase/write в памяти RAM").
[USART/LINUART/UART1/UART2/UART3]
Рис. 21. Команда Write Memory через USART/LINUART/UART1/UART2/UART3 на стороне хоста.
Примечание: см. даташит на используемый MCU, чтобы использовать допустимый адрес. Если начальный адрес недопустимый, то произойдет ошибка add_error (см. таблицу 10).
Хост посылает байты следующим образом.
Байт 1: 0x31 - Command ID. Байт 2: 0xCE - комплемент команды. Bytes 3-6: начальный адрес (32-битный адрес). Байт 3 = MSB. Байт 6 = LSB. Байт 7: контрольная сумма = XOR (байт 3, байт 4, байт 5, байт 6). Байт 8: количество байт для приема -1: N = 0 ... 127. Если N > 127, то в загрузчике произойдет ошибка cmd_error. N+1 байт: максимум 128 байт данных. Байт контрольной суммы: XOR (N,[N+1 байт данных]).
Рис. 22. Команда Write Memory через USART/LINUART/UART1/UART2/UART3 на стороне MCU.
[SPI]
Рис. 23. Команда Write Memory через SPI на стороне хоста.
Примечание (1): здесь нужна задержка Delay или опрос флага занятости BUSY, если устройство это поддерживает. Задержка Delay в миллисекундах вычисляется по формуле: Delay = 8.45 x n. Здесь n это количество циклов записи (количество байт или количество блоков, см. таблицу 8).
Таблица 8. Примеры задержки.
Команда Write Memory
Delay (задержка) в мс
128 байт, выровненных в памяти на границу блока
8.45
128 байт, не выровненных в памяти на границу блока
1082
1 байт
8.45
10 байт
84.5
В режиме SPI, если MCU поддерживает отправку флага занятости BUSY во время программирования памяти Flash/EEPROM, то задержка может быть заменена на опрос состояния MCU (в него посылается набор token-байтов). Во время программирования MCU посылает флаг BUSY (0xAA) через SPI. Когда программирование завершено, MCU посылает ACK/NACK, чтобы показать результат операции - завершилось программирование успешно или неудачно.
В настоящее время такой опрос возможен только для устройств STM8AF/S-medium density с модифицированными подпрограммами RAM (см. "Приложение C. Опции тайминга SPI"). На устройствах STM8L/AL-low density и STM8L/AL-high/medium+ density флаг BUSY flag посылается через интерфейс SPI.
Хост посылает байты следующим образом.
Байт 1: 0x31 - Command ID. Байт 2: 0xCE - комплемент команды. Байт 3 (token): XY; хост ждет ACK или NACK. Байты 4 .. 7: начальный адрес (32-битный адрес). Байт 4 = MSB. Байт 7 = LSB. Байт 8: контрольная сумма = XOR (байт 4, байт 5, байт 6 и байт 7). Байт 9 (token): XY; хост ждет ACK или NACK. Байт 10: количество байт данных для приема -1: N = 0 ... 127); если N > 127, то в загрузчике произойдет ошибка cmd_error. N+1 байт: максимум 128 байт данных. Байт контрольной суммы: XOR (N, [N+1 байт данных]).
Важное замечание: перед отправкой token-байта хост должен подождать, пока загрузчик завершит запись всех данных в память. См. выше описание задержки Delay (или опроса занятости).
Последний байт (token): 0xXY; хост ждет ACK или NACK.
Рис. 24. Команда Write Memory через SPI на стороне MCU.
[CAN]
Рис. 25. Команда Write Memory через CAN на стороне хоста.
Хост посылает сообщения следующим образом.
Соообщение команды: Std ID = 0x31, DLC = 0x05, data = MSB, 0xXX, 0xYY, LSB, N. N = 0 ... 127, количество байт данных -1. Если N > 127, то в загрузчике произойдет ошибка cmd_error. Сообщение данных 1: Std ID = 0x04, DLC_1 = 1 .. 8, data = byte_11, .., byte_18. Сообщение данных 2: Std ID = 0x04, DLC_2 = 1 .. 8, data = byte_21, .., byte_28. Сообщение данных 3: Std ID = 0x04, DLC_3 = 1 .. 8, data = byte_31, .., byte_38. ... Сообщение данных M: Std ID = 0x04, DLC_M = 1 .. 8, data = byte_m1, .., byte_M8. Сообщение контрольной суммы: Std ID = 0x04, DLC = 1, data = XOR (N,[N+1 байт данных]).
Примечания:
(1) DLC_1 + DLC_2 + ... DLC_M = 128 максимум. (2) Загрузчик не проверяет Standard ID в сообщениях данных и контрольной суммы. Поэтому можно использовать ID от 0x00 до 0xFF, но рекомендуется все же использовать ID = 0x04.
Рис. 26. Команда Write Memory через CAN на стороне MCU.
Эта команда позволяет поменять скорость интерфейса CAN во время активной сессии с загрузчиком. Команда Speed может использоваться только если для обмена используется интерфейс CAN.
Рис. 27. Команда Speed через CAN на стороне хоста.
Примечание: после отправки новой скорости (baud rate), загрузчик посылает сообщение ACK на старой скорости. Поэтому хост ждет, пока MCU не отправит ACK, и только после этого меняет свою скорость.
Хост посылает сообщение следующим образом.
Сообщение команды: Std ID = 0x03, DLC = 0x01, data = 0xXX.
Здесь 0xXX подразумевает следующие значения, в зависимости от установленной на основе тактовой частоты HSE скорости:
Команда запускает загруженный код (или любой другой код) путем передачи управления по адресу, указанному хостом.
После того, как команда Go выполнена, области памяти программ и данных находятся в разблокированном состоянии. Приложения должны заблокировать области памяти программы и данных, чтобы установить для памяти состояние защиты по умолчанию.
Для адреса перехода должен использоваться допустимый адрес RAM, памяти программ Flash, EEPROM данных и адрес регистра (см. даташит на используемый NCU). Если загрузчик примет недопустимый адрес, то произойдет ошибка add_error (см. таблицу 10).
[USART/LINUART/UART1/UART2/UART3]
Рис. 29. Команда Go через USART/LINUART/UART1/UART2/UART3 на стороне хоста.
Сообщение команды Go: Std ID = 0x21, DLC = 0x04, data = MSB, 0xXX, 0xYY, LSB.
Рис. 34. Команда Go через CAN на стороне MCU.
Таблица 9. Коды секторов STM8.
Код сектора
Память программ Flash / data EEPROM
STM8AF и STM8S Series high density
STM8AF и STM8S Series medium density
STM8L и STM8AL Series medium density
STM8L и STM8AL Series high/medium + density
STM8L Series low density
0x00
0x008000 .. 0x0083FF
0x01
0x008400 .. 0x0087FF
0x02
0x008800 .. 0x008BFF
0x03
0x008C00 .. 0x008FFF
0x04
0x009000 .. 0x0093FF
0x05
0x009400 .. 0x0097FF
0x06
0x009800 .. 0x009BFF
0x07
0x009C00 .. 0x009FFF
0x08
0x00A000 .. 0x00A3FF
0x001000 .. 0x0010FF
0x09
0x00A400 .. 0x00A7FF
-
0x0A
0x00A800 .. 0x00ABFF
-
0x0B
0x00AC00 .. 0x00AFFF
-
0x0C
0x00B000 .. 0x00B3FF
-
0x0D
0x00B400 .. 0x00B7FF
-
0x0E
0x00B800 .. 0x00BBFF
-
0x0F
0x00BC00 .. 0x00BFFF
-
0x10
0x00C000 .. 0x00C3FF
-
0x11
0x00C400 .. 0x00C7FF
-
0x12
0x00C800 .. 0x00CBFF
-
0x13
0x00CC00 .. 0x00CFFF
-
0x14
0x00D000 .. 0x00D3FF
-
0x15
0x00D400 .. 0x00D7FF
-
0x16
0x00D800 .. 0x00DBFF
-
0x17
0x00DC00 .. 0x00DFFF
-
0x18
0x00E000 .. 0x00E3FF
-
0x19
0x00E400 .. 0x00E7FF
-
0x1A
0x00E800 .. 0x00EBFF
-
0x1B
0x00EC00 .. 0x00EFFF
-
0x1C
0x00F000 .. 0x00F3FF
-
0x1D
0x00F400 .. 0x00F7FF
-
0x1E
0x00F800 .. 0x00FBFF
-
0x1F
0x00FC00 .. 0x00FFFF
-
0x20
0x010000 .. 0x0103FF
0x004000 .. 0x0043FF
0x001000 .. 0x0013FF
0x010000 .. 0x0103FF
-
0x21
0x010400 .. 0x0107FF
-
-
0x010400 .. 0x0107FF
-
0x22
0x010800 .. 0x010BFF
-
-
0x010800 .. 0x010BFF
-
0x23
0x010C00 .. 0x010FFF
-
-
0x010C00 .. 0x010FFF
-
0x24
0x011000 .. 0x0113FF
-
-
0x011000 .. 0x0113FF
-
0x25
0x011400 .. 0x0117FF
-
-
0x011400 .. 0x0117FF
-
0x26
0x011800 .. 0x011BFF
-
-
0x011800 .. 0x011BFF
-
0x27
0x011C00 .. 0x011FFF
-
-
0x011C00 .. 0x011FFF
-
0x28
0x012000 .. 0x0123FF
-
-
0x012000 .. 0x0123FF
-
0x29
0x012400 .. 0x0127FF
-
-
0x012400 .. 0x0127FF
-
0x2A
0x012800 .. 0x012BFF
-
-
0x012800 .. 0x012BFF
-
0x2B
0x012C00 .. 0x012FFF
-
-
0x012C00 .. 0x012FFF
-
0x2C
0x013000 .. 0x0133FF
-
-
0x013000 .. 0x0133FF
-
0x2D
0x013400 .. 0x0137FF
-
-
0x013400 .. 0x0137FF
-
0x2E
0x013800 .. 0x013BFF
-
-
0x013800 .. 0x013BFF
-
0x2F
0x013C00 .. 0x013FFF
-
-
0x013C00 .. 0x013FFF
-
0x30
0x014000 .. 0x0143FF
-
-
0x014000 .. 0x0143FF
-
0x31
0x014400 .. 0x0147FF
-
-
0x014400 .. 0x0147FF
-
0x32
0x014800 .. 0x014BFF
-
-
0x014800 .. 0x014BFF
-
0x33
0x014C00 .. 0x014FFF
-
-
0x014C00 .. 0x014FFF
-
0x34
0x011000 .. 0x0153FF
-
-
0x011000 .. 0x0153FF
-
0x35
0x015400 .. 0x0157FF
-
-
0x015400 .. 0x0157FF
-
0x36
0x015800 .. 0x015BFF
-
-
0x015800 .. 0x015BFF
-
0x37
0x015C00 .. 0x015FFF
-
-
0x015C00 .. 0x015FFF
-
0x38
0x016000 .. 0x0163FF
-
-
0x016000 .. 0x0163FF
-
0x39
0x016400 .. 0x0167FF
-
-
0x016400 .. 0x0167FF
-
0x3A
0x016800 .. 0x016BFF
-
-
0x016800 .. 0x016BFF
-
0x3B
0x016C00 .. 0x016FFF
-
-
0x016C00 .. 0x016FFF
-
0x3C
0x017000 .. 0x0173FF
-
-
0x017000 .. 0x0173FF
-
0x3D
0x017400 .. 0x0177FF
-
-
0x017400 .. 0x0177FF
-
0x3E
0x017800 .. 0x017BFF
-
-
0x017800 .. 0x017BFF
-
0x3F
0x017C00 .. 0x017FFF
-
0x017C00 .. 0x017FFF
-
0x40
0x018000 .. 0x0183FF
-
-
0x001000 .. 0x0013FF
-
0x41
0x018400 .. 0x0187FF
-
-
0x001400 .. 0x0017FF
-
0x42
0x018800 .. 0x018BFF
-
-
-
-
0x43
0x018C00 .. 0x018FFF
-
-
-
-
0x44
0x019000 .. 0x0193FF
-
-
-
-
0x45
0x019400 .. 0x0197FF
-
-
-
-
0x46
0x019800 .. 0x019BFF
-
-
-
-
0x47
0x019C00 .. 0x019FFF
-
-
-
-
0x48
0x01A000 .. 0x01A3FF
-
-
-
-
0x49
0x01A400 .. 0x01A7FF
-
-
-
-
0x4A
0x01A800 .. 0x01ABFF
-
-
-
-
0x4B
0x01AC00 .. 0x01AFFF
-
-
-
-
0x4C
0x01B000 .. 0x01B3FF
-
-
-
-
0x4D
0x01B400 .. 0x01B7FF
-
-
-
-
0x4E
0x01B800 .. 0x01BBFF
-
-
-
-
0x4F
0x01BC00 .. 0x01BFFF
-
-
-
-
0x50
0x01C000 .. 0x01C3FF
-
-
-
-
0x51
0x01C400 .. 0x01C7FF
-
-
-
-
0x52
0x01C800 .. 0x01CBFF
-
-
-
-
0x53
0x01CC00 .. 0x01CFFF
-
-
-
-
0x54
0x01D000 .. 0x01D3FF
-
-
-
-
0x55
0x01D400 .. 0x01D7FF
-
-
-
-
0x56
0x01D800 .. 0x01DBFF
-
-
-
-
0x57
0x01DC00 .. 0x01DFFF
-
-
-
-
0x58
0x01E000 .. 0x01E3FF
-
-
-
-
0x59
0x01E400 .. 0x01E7FF
-
-
-
-
0x5A
0x01E800 .. 0x01EBFF
-
-
-
-
0x5B
0x01EC00 .. 0x01EFFF
-
-
-
-
0x5C
0x01F000 .. 0x01F3FF
-
-
-
-
0x5D
0x01F400 .. 0x01F7FF
-
-
-
-
0x5E
0x10F800 .. 0x10FBFF
-
-
-
-
0x5F
0x10FC00 .. 0x10FFFF
-
-
-
-
0x60
0x200000 .. 0x2003FF
-
-
-
-
0x61
0x200400 .. 0x2007FF
-
-
-
-
0x62
0x020800 .. 0x020BFF
-
-
-
-
0x63
0x020C00 .. 0x020FFF
-
-
-
-
0x64
0x021000 .. 0x0213FF
-
-
-
-
0x65
0x021400 .. 0x0217FF
-
-
-
-
0x66
0x021800 .. 0x021BFF
-
-
-
-
0x67
0x021C00 .. 0x021FFF
-
-
-
-
0x68
0x022000 .. 0x0223FF
-
-
-
-
0x69
0x022400 .. 0x0227FF
-
-
-
-
0x6A
0x022800 .. 0x022BFF
-
-
-
-
0x6B
0x022C00 .. 0x022FFF
-
-
-
-
0x6C
0x022000 .. 0x0223FF
-
-
-
-
0x6D
0x022400 .. 0x0227FF
-
-
-
-
0x6E
0x023800 .. 0x023BFF
-
-
-
-
0x6F
0x023C00 .. 0x023FFF
-
-
-
-
0x70
0x024000 .. 0x0243FF
-
-
-
-
0x71
0x024400 .. 0x0247FF
-
-
-
-
0x72
0x024800 .. 0x024BFF
-
-
-
-
0x73
0x024C00 .. 0x024FFF
-
-
-
-
0x74
0x025000 .. 0x0253FF
-
-
-
-
0x75
0x025400 .. 0x0257FF
-
-
-
-
0x76
0x025800 .. 0x025BFF
-
-
-
-
0x77
0x025C00 .. 0x025FFF
-
-
-
-
0x78
0x026000 .. 0x0263FF
-
-
-
-
0x79
0x026400 .. 0x0267FF
-
-
-
-
0x7A
0x026800 .. 0x026BFF
-
-
-
-
0x7B
0x026C00 .. 0x026FFF
-
-
-
-
0x7C
0x027000 .. 0x0273FF
-
-
-
-
0x7D
0x027400 .. 0x0277FF
-
-
-
-
0x7E
0x027800 .. 0x027BFF
-
-
-
-
0x7F
0x027C00 .. 0x027FFF
-
-
-
-
0x80
0x004000 .. 0x0043FF
-
-
-
-
0x81
0x004400 .. 0x0047FF
-
-
-
-
[Модель программирования (серии STM8AF, STM8AL, STM8L и STM8S)]
Код загрузчика (boot code) разработан с одинаковым логическим протоколом для обмена кадрами команд между хостом и любым устройством (MCU) серий STM8AF, STM8AL, STM8L и STM8S.
Загрузчик может загружать за один раз до 128 байт. Переменные загрузчика занимают RAM от адреса 0x000000 до адреса 0x00009F.
Если загрузчик был разрешен (в соответствии с таблицей 4), и истекли таймауты (не произошла активация хоста, или произошел переход в приложение пользователя), то содержимое RAM может остаться измененным загрузчиком. Например, если пользовательское приложение запустилось, и произошел сброс, то содержимое RAM в диапазоне адресов 0x000000 .. 0x00009F будет изменено загрузчиком до перезапуска приложения.
Если загрузчик запрещен с помощью байта опций или активацией защиты ROP, то необходимо произвести следующие незначительные изменения в приложении пользователя:
• Версии MCU серий STM8L и STM8AL, и последних серий STM8AF и STM8S (см. таблицу 3): RAM не меняется загрузчиком. • Версии MCU серий STM8AF и STM8S с более старыми версиями загрузчика: RAM меняется по адресам 0x000095 и 0x000099.
Примечание: не используемое (пустое) пространство bootloader ROM заполнено недопустимым кодом операции (0x71). Если по любой причине (например, из-за шума EMC) ядро начнет выполнять код в области, заполненной 0x71, то произойдет ошибка недопустимой операции (illegal opcode) и последующий сброс. Это предотвращает вход загрузчика в бесконечное зацикливание (зависание) без возможности автоматического сброса, когда произошел случайный переход по "пустому" адресу. Таким образом может произойти восстановление нормального выполнения программы.
[Подпрограммы erase/write в памяти RAM]
Подпрограммы RAM erase/write прикреплены к этому документу как двоичный код в формате S19. Имя файла определяет группу STM8 (т. е. 128 килобайт, 32 килобайта, 8 килобайт) и номер версии загрузчика, для которого эта подпрограмма написана.
Чтобы стереть или запрограммировать память программ Flash или data EEPROM, должны быть загружены соответствующие подпрограммы в RAM, начиная с адреса 0x0000A0.
Пример именования RAM подпрограммы erase/write:
• 128-килобайтные устройства (high density) серий STM8AF и STM8S: E_W_ROUTINEs_128K_ver_2.2.s19. • 32-килобайтные устройства (medium density) серий STM8AF и STM8S: E_W_ROUTINEs_32K_ver_1.3.s19. • 8-килобайтные устройства (low density) серий STM8L и STM8AL: E_W_ROUTINEs_8K_verL_1.0.s19 (это только патч для сохраненной внутри подпрограммы RAM: загрузится один байт 0xB2 по адресу 0x01EA). • Устройства серий STM8L и STM8AL: подпрограммы загружать не нужно, они копируются в RAM автоматически из ROM, когда загрузчик активируется хостом (после того, как загрузчик получил допустимый байт SYNCH).
Чтобы выполнить любую команду (Get, Read, Erase, Write, Speed и Go) загрузчик использует часть RAM для своих собственных переменных и подпрограмм RAM erase/write. Поэтому запрещено выполнять команды записи (за исключением команд записи, которые используются для загрузки подпрограмм erase/write) с адресами назначения в следующих областях RAM:
• MCU серий STM8AF и STM8S: от 0x000000 до 0x0001FF. • MCU серий STM8L и STM8AL: от 0x000000 до 0x0001FF.
[Обработка ошибок]
Загрузчик выполняет несколько внутренних проверок, включая проверку на допустимый диапазон адреса в командах, проверку контрольных сумм команд и верификацию записи. Загрузчик не проверяет доступ в область UBC. Если запись производится в область, защищенную от записи, то верификация завершится с ошибкой и загрузчик вернет NACK.
Таблица 10 описывает типы ошибки и соответствующее поведение загрузчика.
Таблица 10. Ошибки загрузчика.
Ошибка
Описание
Действия загрузчика
cmd_error
Если принята запрещенная команда. Если произошла ошибка проверки четности (parity error) во время передачи команды. Если произошла ошибка во время выполнения команды (см. таблицу 6 со списком команд загрузчика).
Отправит байт NACK и вернется к проверке приходящих команд.
add_error
Если принятая команда содержит запрещенный адрес назначения. Для получения информации о допустимых диапазонах адресов см. даташиты на микроконтроллеры STM8AF/AL/L/S.
[Время программирования]
Сколько займет времени программирование, зависит от скорости используемого для обмена периферийного устройства. Примеры времени программирования включают измерения для следующих интерфейсов и скоростей:
Примечание: измерения производились на блоках 48 килобайт или 32 килобайта, независимо от типа MCU и используемого периферийного устройства. Таблицы 11, 12 и 13 показывают время программирования данных в память прогамм Flash соответственно для USART/LINUART/UART1/UART2/UART3, SPI и CAN.
Таблица 11. Время программирования через USART/LINUART/UART1/UART2/UART3.
Функция защиты от чтения ROP предотвращает от несанкционированного чтения памяти MCU через интерфейс SWIM. Во время своей инициализации загрузчик проверяет состояние ROP (анализом содержимого байта опций ROP), и если защита ROP разрешена, то загрузчик не активируется. Это предотвращает возможность считывания прошивки и данных через загрузчик (или возможности записи и выполнения троянского кода).
Однако на практике может понадобится не только использование защиты ROP, но и обновление прошивки, чтобы можно было записать новое firmware через IAP. Это может быть сделано через приложение пользователя и взаимодействие с загрузчиком по следующим правилам.
[Правила для обновления устройств, которые защищены ROP]
1. Устройство должно быть защищено активацией ROP (что запрещает чтение памяти через SWIM).
2. Загрузчик не активируется после сброса из-за проверки состояния ROP (чтобы запретить чтение памяти через загрузчик).
3. Приложение пользователя отвечает за разрешение обновления после аутентификации пользователя, например после проверки ввода пароля.
4. Приложение пользователя после успешной проверки аутентификации позволяет запустить загрузчик (выполнением jump по специфическому адресу загрузчика). После этого загрузчик может обновить приложение пользователя обычным образом.
По приведенным выше правилам приложение пользователя может быть обновлено через резидентный загрузчик, находящийся в ROM. Единственное условие заключается в том, что приложение пользователя (firmware) должно взаимодействовать с процессом выгрузки, как описано ниже:
• В приложении должна быть реализована процедура аутентификации (например, отправка специальной команды с паролем через интерфейс коммуникации). • Приложение должно сделать передачу управления в точку "ROP check", где проверяется точка входа загрузчика (чтобы обойти проверку ROP загрузчиком). См. таблицу 14 в приложении B, где приведены адреса точек входа в загрузчик.
ROM-загрузчик может быть активирован хостом после сброса устройства (см. выше секцию "Активация загрузчика"). Однако загрузчик может также использоваться в приложении пользователя для различных целей. В таблице 14 перечислены основные точки входа в загрузчик, и описано, как они могут использоваться в приложении пользователя.
Таблица 14. Точки входа в загрузчик (bootloader entry point).
Название точки входа
Адрес (версия загрузчика)(1)
Использование
STM8AF и and STM8S Series high density
STM8AF и STM8S Series medium density
STM8L и STM8AL Series medium density
STM8L и STM8AL Series high/ edium+ density
STM8L и STM8AL Series low density
Reset
0x006000
Отсюда загрузчик запускается. Может использоваться для жесткого сброса.
BL option check
0x00601E (v2.1)(2) 0x00601E (v2.2)
0x00601E (v1.2)(3) 0x006018 (v1.3)
0x00601A (v1.1) 0x00601F (v1.2)
0x00601F (v1.1)
0x00601F (v1.0)
Место после проверки, разрешен ли загрузчик байтами опций. Может использоваться для запуска загрузчика из firmware пользователя, когда запуск загрузчика после сброса запрещен байтами опций.
ROP check
0x00602E (v2.1)(2) 0x00602E (v2.2)
0x00602E (v1.2)(3) 0x006028 (v1.3)
0x006028 (v1.1) 0x00602D (v1.2)(4)
0x00602D (v1.1)
0x00602D (v1.0)
Место после проверки защиты от записи. Может использоваться для запуска загрузчика из firmware пользователя, если активна защита ROP - для обновления устройства, защищенного ROP (после аутентификации пользователя).
Примечания:
(1) Адрес зависит от версии загрузчика, и может быть изменен в его следующей, более новой версии. За последней информацией свяжитесь с локальным офисом STMicroelectronics. (2) Для этой версии загрузчика переменная RAM по адресу 0x000099 должна быть установлена в значение 0x00 или 0x01 (0x00 = без таймаута, 0x01 = 1 секунда таймаута загрузчика). (3) Для этой версии загрузчика переменная RAM по адресу 0x000095 должна быть установлена в значение 0x00 или 0x01 (0x00 = без таймаута, 0x01 = 1 секунда таймаута загрузчика). (4) Для версии загрузчика 1.0 не определена точка обхода проверки защиты чтения (ROP check entry point).
Перед jump в точку входа загрузчика приложение должно сконфигурировать все используемые периферийные устройства (таймеры, периферийные устройства коммуникационных интерфейсов, ножки GPIO этих периферийных устройств) в их состояние по умолчанию после сброса, чтобы загрузчик мог корректно продолжить свое выполнение. Загрузчик был разработан с таким расчетом, что на входе получает состояние MCU после сброса (когда все периферийные устройства находятся в своем состоянии по умолчанию).
Для всех MCU перед тем, как сделать jump на точку входа в загрузчик, необходимо обновить теневые регистры прескалера TIM2 и TIM3 (prescaler shadow registers) в значение 1 с помощью следующего рекомендуемого кода:
...
// Запуск события обновления (update event),
// чтобы прескалер TIM3 обновился в значение 1:
TIM3->EGR =0x01;
// Очистка генерируемого флага update event
// в бите TIM3_SR1 с помощью чтения и записи
// в него нуля:
TIM3->SR1;
TIM3->SR1 =0x00;
// jump, передача управления на адрес точки входа:
_asm("jp 0x601E");
...
Во врезках с описанием команд Erase Memory и Write Memory, работающих через SPI, содержатся рисунки с алгоритмом работы этих команд. Недостаток SPI в том, что хост управляет транзакциями с помощью опроса данных из MCU. Если MCU занят (например, он программирует память Flash), то хост получит ответ в виде последнего байта, который был записан в регистр данных SPI (это последний отправленный байт с момента предыдущего опроса). Так что у хоста нет способа определить, был ли принятый от MCU байт корректным (новым) ответом, или же это байт от предыдущего ответа.
На практике, если хост запрашивает MCU выполнить текущую команду стирания или записи (ACK или NACK от MCU после завершения операции), то хост знает, что устройство не занято и завершило операции. Таким образом, хост должен добавить подходящую минимальную задержку, чтобы позволить MCU закончить операцию (см. блок "Delay" на рис. 17 и 23). Иначе ответ не имеет смысла, и обмен получится рассинхронизированный.
Такое поведение специфично только для тех интерфейсов, работой которых управляет хост (мастер шины), таких как интерфейс SPI. Другие интерфейсы, используемые в загрузчике, включая UART и CAN, не управляются жестко мастером (и с ними MCU имеет возможность самому выполнить передачу данных без опроса хостом).
[Модифицированные RAM-подпрограммы erase/write]
Чтобы избавиться от зависимости реализации задержки на стороне хоста и ускорить обмен SPI (потому что задержка с запасом оказывается дольше времени завершения операции), разработаны специальные RAM-подпрограммы erase/write. Эти подпрограммы выполняют длительные по времени операции так же, как и стандартные операции erase/write. Когда MCU занят, он отправляет в виде ответа хосту байт занятости BUSY (0xAA). Хост может периодически запрашивать от устройства ответ, если пришел ответ BUSY, то это значит, что операция еще не завершена. После завершения операции MCU ответит байтом ACK или NACK, в зависимости от результата операции. Тогда блок алгоритма "Delay" на рисунках 17 и 23 заменяется циклом опроса, пока не будет принят ответ ACK или NACK.
Рис. 35. Удаление задержки (Delay) в модифицированных RAM-подпрограммах.
Модифицированные RAM-подпрограммы erase/write для поддержки опроса SPI предоставляются для 32-килобайтных MCU STM8AF/S. MCU STM8L/AL сами поддерживают подпрограммы RAM с ответом состояния BUSY (для них копировать подпрограммы erase/write не нужно).
Для поддержки загрузчика фирма STMicroelectronics предоставила демонстрационное приложение PC, известное как "Flash loader demonstrator", которое позволяет обновить firmware в STM8 через интерфейс UART (на стороне PC это традиционный RS-232 или виртуальный COM-порт USB CDC). Это ПО работает под операционной системой Microsoft® Windows®, и его можно загрузить с сайта www.st.com.
С этим ПО любое firmware, сохраненное в файл *.s19, может быть выгружено в устройство STM8AF/AL/L/S. ПО также выполняет проверку выгруженного firmware и автоматическое стирание памяти.
Ограничение для загрузчика введено не из-за того, что загрузчик реализован неправильно, и не из-за несовместимости со спецификациями. Причина в специфике применения STM8 ROM bootloader конечным пользователем.
Чтобы предотвратить возникновение проблем, используйте способ обхода ограничения загрузчика UART, описанный далее, когда это необходимо.
[Автоопределение скорости UART]
Как упоминалось выше в секции описания настроек USART/UART, загрузчик опрашивает все периферийные устройства (UART, SPI, CAN) в ожидании байта синхронизации. Обмен с загрузчиком начинается, когда принятый байт синхронизации равен 0x7F.
Для обмена данными через UART скорость, с которой передаются данные, изначально неизвестна для загрузчика. Для SPI и CAN ситуация другая, потому что скорость SPI задается тактами хоста, а для CAN скорость по умолчанию фиксирована на 125 килобит/сек.
Перед инициализацией интерфейса UART загрузчик анализирует длительности на ножке приема UART (ножка RxD GPIO), ожидая байта синхронизации 0x7F, и по его измеренным длительностям нулей и единиц вычисляет скорость передачи. Это называется автоопределением скорости UART.
1. Мастер посылает 0x7F в виде последовательного кадра (LSB идет первым) на вход интерфейса UART. Байт 0x7F состоит из следующих частей:
– Start-бит (лог. 0). – 7 следующих друг за другом бит лог. 1 (LSB бит идет первым). – 1 бит в лог. 0 (MSB бит байта 0x7F). – Бит четности even (лог. 1). – Stop-бит (лог 1).
2. Загрузчик опрашивает уровень на ножке RxD, ожидая появления start-бита (лог. 0).
3. В момент перепада от 0 к 1 (окончание start-бита) загрузчик запускает таймер, чтобы по его счетчику измерить длительность 7 логических единичек.
4. Загрузчик останавливает таймер по спаду уровня RxD (завершение 7 следующих друг за другом бит лог. 1, в момент начала MSB). Количество тиков таймера соответствует длительности 7 логических единиц байта синхронизации 0x7F. По счетчику таймера загрузчик вычисляет длительность одного бита (количество тиков делится на 7), по этой длительности вычисляет скорость UART (baudrate), и соответствующим образом инициализирует скорость периферийного устройства UART. После этого загрузчик готов к принятию следующей команды от хоста.
[Описание ограничения UART]
Автоматическое вычисление скорости подразумевает, что хост отправит 0x7F в качестве байта синхронизации. Однако вычисление скорости будет неправильным, если хост отправит байт, отличающийся от 0x7F, потому что загрузчик ожидает семи следующих друг за другом лог. 1 вслед за start-битом фрейма. В этой ситуации возобновить обмен поможет только сброс MCU STM8.
Следовательно, хост должен отправить 0x7F после сброса, чтобы корректно запустить загрузчик на интерфейсе UART, либо не должен ничего посылать в течение 1 секунды после сброса, чтобы загрузчик не запустился, и начало выполняться приложение пользователя. Любой другой байт, отправленный загрузчику в течение 1 секунды после сброса, приведет к входу загрузчика в бесконечный цикл ожидания команды не неправильно определенной скорости.
Такая ситуация может возникнуть в приложении пользователя, если STM8 было сброшено в тот момент, когда большой объем данных передается через интерфейс UART. Тогда устройство войдет в бесконечный цикл загрузчика из-за приема нескольких "байт синхронизации".
[Обход ограничения UART]
Проблема, описанная выше, может быть исправлена по следующей методике. Она основана на модификации кода приложения и конфигурации MCU. Это рекомендуется, если Ваше приложение при запуске входит в бесконечный цикл, когда начинается обмен через UART. Необходимо выполнить следующие шаги:
1. Запретите загрузчик байтами опций (на чистых MCU загрузчик запрещен). 2. Вставьте в код своего приложения подпрограмму, которая запустит загрузчик, когда необходимо обновление firmware. Например, код приложения должен делать jump в указанную точку входа загрузчика (bootloader entry point, см. таблицу 14 в приложении B).
В результате при сбросе загрузчик не активируется, и устройство не войдет в бесконечный цикл, когда примет через UART случайные байты. После сброса загрузчик сразу запустит код приложения без всякой задержки, что также выглядит для приложения как дополнительное преимущество.
Если необходимо обновить код приложения, выполните следующую последовательность действий:
1. Нажмите специальную кнопку, которая активирует загрузчик с помощью передачи управления на указанную bootloader entry point. Необходимо гарантировать, что к UART при этом подключен хост, и он не отправляет никаких случайных байт. 2. Запустите хост для обновления кода с помощью стандартного ROM bootloader. 3. Сбросьте устройство, когда обновление завершится.
Описанный способ запуска загрузчика с помощью кнопки может быть заменен другим условием запуска загрузчика, например с помощью отправки через интерфейс специальной команды или пароля аутентификации (чтобы обновить firmware мог только авторизованный персонал).
Операция программирования может потерпеть крах в процессе обновления (например, из-за неожиданного отключения питания устройства). Тогда в загрузчик снова войти не получится, потому что код приложения не был корректно обновлен. Чтобы предотвратить возникновение такой проблемы, рекомендуется, чтобы хост выполнил следующие шаги перед входом в загрузчик:
1. Разрешение ROM bootloader через байты опций перед загрузкой кода приложения в устройство. 2. Загрузка кода приложения обычным способом с помощью ROM bootloader и проверка загрузки. 3. Повторный запрет ROM bootloader байтами опций.
Определенная группа STM8 связана с определенным кодом загрузчика. Этот код с течением времени подвергается улучшениям, и появляются новые версии загрузчика. Отличия разных версий загрузчика суммарно показаны в таблице 15 вместе с ограничениями, улучшениями и добавленными функциями.
Таблица 15. Описание ограничений, улучшений и добавленных функций в разных версиях загрузчика.
Группа STM8
Версия загрузчика
Ревизия MCU
Ограничения, улучшения и добавленные функции
STM8AF и STM8S Series high density
2.1
Rev X
Начальная версия. Ограничения: – Такты CPU установлены в HSI/1 (16 МГц), когда загрузчик возобновляет работу. – Интерфейс CAN работает некорректно. Свяжитесь с ближайшим офисом продаж STMicroelectronics для получения инструкций по обходу проблемы CAN в этой версии загрузчика.
2.2
Rev U и T: STM8AFxxxx52xx, STM8AF6269/8x/Ax Rev Y, 6, W, 7: STM8S207/208xx
Улучшения: – Защита от блокировки EMC. Исправлены ограничения: – Настройка тактов CPU возвращается обратно в состояние по умолчанию после сброса, когда загрузчик возобновляет работу. – Периферийное устройство CAN работает корректно.
Начальная версия. Ограничения: – Такты устанавливаются на 16 МГц после команды Go (прескалер HSI не устанавливается обратно в состояние по умолчанию после сброса).
Улучшения: – Защита от блокировки EMC. Исправлены ограничения: – После команды Go используется тактовый генератор HSI. Добавленная функция: – Периферийное устройство SPI использует флаг BUSY (см. Приложение C).
STM8L и STM8AL Series high/medium+ density
1.0
Rev A
Начальная версия. Улучшение: – Защита от блокировки EMC. Ограничение: – Запрещается проверка загрузчика, когда он возобновит работу.
1.1
Rev Z
Исправлено ограничение: - Проверка загрузчика не запрещается, когда он возобновит работу.
STM8L и STM8AL Series medium density
1.0
Rev A
Начальная версия. Ограничения: – Не проверяется бит защиты от чтения (ROP). – Такты CPU устанавливаются на HSI/1 (16 МГц), когда загрузчик возобновляет работу. – Таймаут на получения байта SYNCH после сброса составляет 500 мс вместо 1 секунды.
1.1
Rev B
Ограничения: – Такты CPU устанавливаются на HSI/1 (16 МГц), когда загрузчик возобновляет работу. – Таймаут на получения байта SYNCH после сброса составляет 500 мс вместо 1 секунды. Исправлено ограничение: – Теперь проверяется бит защиты от чтения.
1.2
Rev Z
Улучшение: – Защита от блокировки EMC. Ограничения: – Если загрузчик разрешен, то после передачи управления в приложение (после истечения 1 секунды таймаута или после выполнения команды Go) устанавливаются некорректные ключи MASS в регистре FLASH_PUKR. Эта операция блокирует будущие настройки состояния без защиты от записи для памяти программ. Из-за того, что память программ установлена на запись незащищенного состояния во время инициализации загрузчика, она остается в таком состоянии до тех пор, пока не будет активирована защита. Если в приложении требуется функционал IAP, то приложение никогда не должно защищать от записи память программ, иначе защита от записи останется активированной до следующего сброса устройства. – Если загрузчик разрешен, то перед переходом в приложение (после таймаута в 1 секунду) память данных остается незащищенной (она не была защищена во время инициализации загрузчика). Для повышения надежности приложения нужно активировать защиту от записи для памяти данных. – Если ROP активна, но загрузчик разрешен байтами опций, то загрузчик устанавливается некорректные ключи MASS в регистре FLASH_PUKR (сразу после проверки ROP). Эта операция навсегда оставляет память программ в состоянии защиты от записи. Если в приложении требуется функционал IAP (с активной ROP) то загрузчик должен быть запрещен байтами опций. Исправлены ограничения: – Тактирование CPU возвращается обратно в состояние после сброса, когда загрузчик возобновляет работу. – Таймаут для приема байта SYNCH после сброса установлен на 1 секунду.
STM8L Series low density
1.1
Rev Z
Начальная версия. Ограничения: – Если загрузчик разрешен, то перед переходом в приложение (после таймаута в 1 секунду) память данных остается незащищенной (она не была защищена во время инициализации загрузчика). Для повышения надежности приложения нужно активировать защиту от записи для памяти данных.
Все группы
Все версии
Все ревизии
Когда загрузчик производит передачу управления в приложение после 1 секунды таймаута, прескалер для TIM3 не получает значение по умолчанию (коэффициент деления 1). Регистр прескалера TIM3_PSCR имеет корректное значение по умолчанию (0x0000), но оно передается в прескалер только после события обновления TIM3. Поэтому в приложении, когда загрузчик разрешен, , необходимо генерировать событие обновления (установить бит UG в регистре TIM3_EGR) чтобы значение регистра TIM3_PSCR было передано в физический прескалер. Иначе прескалер будет установлен в некорректный коэффициент деления до тех пор, пока не произойдет следующее событие обновления TIM3.
[Словарик]
ACK acknowledge, положительное подтверждение (отрицательным подтверждением будет NACK).
BCD binary-coded decimal, двоично-десятичное число. Из Википедии: 8421-BCD это форма записи рациональных чисел, когда каждый десятичный разряд числа записывается в виде его четырёхбитного двоичного кода. Таким образом, каждая тетрада двоично-десятичного числа может принимать значения от 00002 (010) до 10012 (910). Например, десятичное число 31110 будет записано в двоичной системе счисления в двоичном коде как 1 0011 01112, а в двоично-десятичном коде как 0011 0001 0001BCD.
BL bootloader, загрузчик.
bps bit per second, скорость в бит/сек.
DFU Direct Firmware Update, дословный перевод "прямое обновление микропрограммы". Термин обозначает технологию обновления прошивки MCU с использованием встроенного загрузчика.
GPIO general purpose input/output, входы/выходы общего назначения.
IAP in-application programming, программирование в системе. То же самое, что и ISP.
ISP in-system programming, программирование в системе. То же самое, что и IAP.
HSE high speed external, высокоскоростная внешняя тактовая частота (определяется подключенным кварцем или внешним генератором).
HSI high speed internal, внутренняя высокоскоростная тактовая частота.
LSB least significant bit, самый младший значащий бит. Также, в зависимости от контекста, может означать самый младший байт.
MCU microcontroller unit, микроконтроллер.
MSB most significant bit, самый старший значащий бит. Также, в зависимости от контекста, может означать самый старший байт.
NACK negative acknowledge, отрицательное подтверждение (положительным подтверждением будет ACK).
NSS node select slave, сигнал для выборки подчиненного устройства на шине SPI.
RAM random access memory, память с произвольным доступом, оперативная память, ОЗУ.
ROM read-only memory, память только для чтения, постоянная память, ПЗУ.
ROP readout protection, защита от чтения кода.
routine подпрограмма.
SWIM single wire interface module, однопроводный интерфейс отладки, встроенный в микроконтроллер.
SW reset программный сброс.
token токен, пустой произвольный байт, служит для получения и приема подтверждения ACK или NACK. Токен используется из-за особенности реализации SPI - обмен в обе стороны происходит одновременно, т. е. подчиненное устройство (в нашем случае подчиненным устройством служит MCU) может отправить свое подтверждение только если хост передаст произвольный байт (токен).
UBC user boot code, память, предназначенная для загрузчика.
WM сокращение от Write Memory (рис. 1).
[Ссылки]
1. UM0560 User manual STM8 bootloader site:st.com. 2. 201128UM0560-Flasher-STM8.zip - документация, демонстрационная утилита для работы с загрузчиком STM8. 3. UM0470 STM8 SWIM communication protocol and debug module site:st.com.