Прошивка микроконтроллера К1986ВЕ92QI через UART и SWD с использованием ST-LINK

Отладочная плата LDM-K1986BE92QI содержим микроконтроллер Миландр К1986ВЕ92QI (или MDR32F9Q2I). Способы прошивки МК (загрузки прошивки в ПЗУ) описаны в разделе 8 спецификации. Рассмотрим 2 способа прошивки микроконтроллера на данной плате.

Прошивка микроконтроллера Миландр с помощью COM-порта

Для прошивки с помощью СОМ-порта не требуются внешние программаторы.

Прошивкой с помощью СОМ-порта можно оживить микроконтроллер если, например, заблокированы ПО выводы JTAG (SWD) и прошивка программатором становится невозможной.

При прошивке с помощью COM порта МК ожидает загрузки кода с интерфейса UART и запуск любого некорректного кода из других мест недоступен.

Для программирования МК через UART необходимо выполнить следующие действия:

1) Подключить mini-USB кабель к верхнему левому соединителю на отладочной плате LDM-K1986BE92QI, он подписан как "USB A USB UART". Включить питание платы и убедиться что в ОС Windows в диспетчере устройств. При необходимости установить драйвер USB-UART. В соответствии с рисунком 1, в системе подключенная отладочная плата должна определиться как СОМ-порт, например, на рисунке 1 это COM6, вы должны запомнить свой номер;

Рисунок 1. Подключенная к ПК отладочная плата (к соединителю USB-A) должна определиться как COM-порт.

2) На отладочной плате LDM-K1986BE92QI выставляем тремя большими черными переключателями с подписью "UDM mode M2...M0 101" значение 101, это крайние переключатели вверх, средний вниз. Когда переключатель включен вверх над ним загорается соответствующий светодиод. Данные переключатели определяют откуда будет загружаться программа МК.

3) Открываем программу USB-UART загрузчик и устанавливаем путь к прошивке *.hex, параметры COM-порта и режимы загрузки в соответствии с рисунком 2.

Рисунок 2. Настройки программы 1986WSD для прошивки МК через UART (COM-порт).

4) Нажимаем кнопку "Start+Run" должна зашиться в МК прошивка, он должен автоматически стартовать и загрузиться с ней. У меня получается успешно прошить далеко не с первого раза, если не помогает, нужно нажать кнопку с надписью "RESET" на отладочной плате (или выключить и включить питание кнопкой питания) и затем кнопку "Start+Run" в ПО 1986WSD. На рисунке 3 ниже показано неудачная и удачная прошивка МК.

Рисунок 3. Примеры неудачной и удачной прошивки МК.

После успешной прошивки МК должен моргать светодиод VD5 на отладочной плате LDM-K1986BE92QI

Прошивка микроконтроллера Миландр с помощью SWD и ST-Link

Более продвинутый способ прошивки МК чем через интерфейс UART является прошивка через интерфейс JTAG или SWD, дающие следующие преимущества в сравнении с использованием UART:
1) Прошивка МК занимает гораздо меньше времени, так как SWD, по умолчанию работают на частоте 4 МБит/сек, а UART 115200 Бит/сек.
2) Прошивка происходит прямо из среды разработки Keil, нажимаем клавишу F7 для сборки проекта и клавишу F8 для прошивки МК - бинго!

Для подключения интерфейса JTAG необходимо подключить к программатору 6 проводов, а для подключения интерфейса SWD всего 3 провода. Поэтому мы будем использовать интерфейс SWD и один из самых распространенных и дешевых отладчиков и программаторов ST-Link, приведенный на рисунке 4.

Рисунок 4. Программатор ST-Link для прошивки и отладки микроконтроллеров Миландр через интерфейс JTAG или SWD (цвет корпуса может быть любым).

После подключения ST_LINK к ПК и установке драйверов он должен быть отображен в диспетчере устройств в соответствии с рисунком 5.

Рисунок 5. ST_LINK в диспетчере устройств Windows.

У МК К1986ВЕ92QI два JTAG(SWD) интерфейса. Приведем таблицу с необходимыми соединениями отладчика и МК (отладочной платы LDM-K1986BE92QI).

ST-Link JTAG A
UDM MODE[2:0] = 001
JTAG B
UDM MODE[2:0] = 000
SWCLK
(вывод 2)
TCK
(вывод 9 XS5)
TCK
(вывод 9 XS6)
SWDIO
(вывод 4)
TMS
(вывод 7 XS5)
TMS
(вывод 7 XS6)
GND
(вывод 6)
GND
(вывод 4, 6, 8, 10, 12, 14, 16, 18, 20 XS5)
GND
(вывод 4, 6, 8, 10, 12, 14, 16, 18, 20 XS6)

Нумерация выводов соединителей на отладочной плате LDM-K1986BE92QI приведено на рисунке 5.

Рисунок 6. Нумерация соединителей и выводов на отладочной плате LDM-K1986BE92QI.

Следует учитывать что выводы связанные с интерфейсами JTAG (SWD) также являются портами ввода-вывода и ряда периферийных устройств и нужно решать что использовать - JTAG (SWD) или периферию.

Заблокировать порты JTAG (SWD) можно если писать в их порты не единицы, что указано во втором абзаце пункта 16 спецификации микроконтроллеров серии 1986ВЕ9х и К1986ВЕ9х. Так, например, используя для прошивки МК интерфейс SWD от JTAG A мы блокируем только порты PB2 (TCK) и PB1 (TMS), но ниже приведенная запись в порт PB0, который не используется в SWD сделает невозможной дальнейшую прошивку или отладку.


MDR_PORTB->RXTX ^= (1 << 0); // Запись в PB0 заблокирует SWD использующий PB1 и PB2 т.к. если в них были при чтении регистра 1, то и записываться будут 1 - ЧТО ЗАПРЕЩЕНО!

Если такое произошло, исправляем программу, переключаем UDM MODE в UART (101) и перешиваем МК через UART. А что? Дурак и должен жить плохо!

Перепишем нашу программу с учетом защиты SWD от блокировок.


#include "MDR32F9Q2I.h"

#define PIN_LED 3	// Номер вывода светодиода

int main (void){
  uint32_t val_b; // Переменная для хранения значения регистра B
  for(int i = 0; i < 1000000; i++){} // Задержка	которая даст нам время на прошивку через SWD, код блокирующий интерфейс может быть только дальше
  
  MDR_RST_CLK->PER_CLOCK |= (1 << 22); // Разрешение тактирования порта B (п.14.7.8)

// Инициализация вывода со светодиодом, порта B как выхода.
  MDR_PORTB->OE |= (1 << PIN_LED); // Вывод является выходом (п.16.1.2). Обязательно устанавливать в 1.
  MDR_PORTB->ANALOG |= ((1 << PIN_LED)); // Режим работы - цифровой (п.16.1.4) Обязательно устанавливать в 1.
  MDR_PORTB->PWR |= (1 << PIN_LED * 2); // Включить передатчик. Скорость фронта вывода - медленная (п.16.1.7). Обязательно устанавливать в 1, 2 или 3.
	
  	
  while(1){
    for(int i = 0; i < 100000; i++){} // Задержка
      
    val_b = MDR_PORTB->RXTX; // Считываем значение регистра B
    val_b &= ~((1u << 1) | (1u << 2)); // Сбросить 1й и 2й бит в 0 (выводы SWD PB1 и PB2)
    val_b ^= (1 << PIN_LED); // Инвертировать значение бита порта B со светодиодом 
    MDR_PORTB->RXTX = val_b; // Записываем значение в регистр. Теперь мы уверены что в PB1 и PB2 будут писаться нули, независимо от того что в них было при чтении.
  }
}

Выше приведен пример программы с мигающим светодиодом и защиты порта SWD (JTAG A) от блокировки. Тут применено 2 вида защиты:
1) Сразу в начале функции main() идет задержка перед любым кодом и возможным блокированием порта SWD, дающая пару секунд на нажатие клавиши F8 (прошивки МК). Из минусов на те же пару секунд задерживается выполнение программы при старте.
2) В цикле while() применено принудительное зануление значений битов соответствующих SWD. Из минусов - код более громоздкий и медленный, но - всё чего-то стоит..
Поменяем бит со светодиодом на 2


#define PIN_LED 3	// Номер вывода светодиода
Компилируем прошиваем. Теперь мы точно блокируем вывод PB2(TCK) и интерфейс SWD.
Пробуем еще раз прошить МК - и у нас ничего не получается!
Нажимаем на отладочной плате кнопку RESET (в нижнем правом углу) и сразу же нажимаем F8 - должен успешно прошиться МК и таким образом работает защита №1.
2024-04-28



Понравилась страница?
Добавить в закладки
Или поделиться!

Связанные темы

Управление тактовой частотой микроконтроллера Миландр К1986ВЕ92QI (MDR32F9Q2I)
Работа с портами ввода-вывода (GPIO) микроконтроллера Миландр на CMSIS
Прерывания в микроконтроллерах Миландр. Системный таймер.
Настройка среды разработки для микроконтроллеров Миландр (К1986ВЕ92QI)
Прошивка микроконтроллера К1986ВЕ92QI на отладочной плате LDM-K1986BE92QI через UART и SWD с использованием ST-LINK
Работа с UART микроконтроллера К1986ВЕ92QI (MDR32F9Q2I)