Практика говорит, что всегда прежде чем прошить в контроллер что-то новое, сделайте резервную копию текущей прошивке. В один прекрасный момент я сделал программатор тут, но не смог найти готовый софт для считывания прошивки для контроллера cc2541 (bluetooth модуль MLT-BT05) и решил на свой страх и риск залить в него новую прошивку. Результат ожидаемый - модуль не работает.
Не буду рассказывать, как собрать и подключить программатор, так как это уже было описано в моей статье достаточно подробно. Сразу перейдем к написанию и проверке считывателя прошивок.
План
1. Разбираемся с командами режима debug сс2542
2. Модифицировать arduino скетч из моей статьи. Arduino будет в роли программатора
3. Написать программу на Python (взамен CCLoader) с помощью которой будем отправлять команды на программатор и сохранять файл с прошивкой на компьютер.
4. Все подключить и считать прошивку
5. Проверить корректность
1. Режим debug сс2541
В режиме отладки контроллер может принимать команды в основном длиной от 1 до 4 байт, кроме команд блочной записи и чтения (2025байт).
Команда = код команды + байты с данными для команды
В ответ котроллер высылает байты с результатом.
Lлину команд на отправку и количество получаемых данных можно увидеть в таблице:
Как видим команда получения идентификатора чипа 1 байт, а команда DEBUG_INSTR 3 байта.
Хотел бы обратить внимание на команду DEBUG_INSTR - это команда исполняет любую инструкцию внутри cc2541, которую мы передадим в качестве аргумента, а в ответ вернет значение регистра аккумулятора.
Именно таким образом происходит чтение и запись данных из cc2541. А так же можно выполнить любую инструкцию системы команд 8051 контроллера.
Например выполнил на котроллере MOV A,1 - поместим регистр аккумулятора единицу:
1 Байт: 0x54 = (0101 0111) - DEBUG_INSTR 3 байта
2 Байт: 0x74 = (0111 0100) - MOV A,X - то есть копирование X в А
3 Байт: 0x01 = (0000 0001) - Значение X=1
В ответ получим результат длиной в 1 байт. который всегда содержит значение 8-битного регистра A.
1 Байт: 0x01 = (0000 0001)
2. Модифицируем arduino скетч
1. Берем скетч программатора.
2. удаляем функцию loop() - в конце программы
3. Вставляем в конец часть кода по этой ссылке
Должно получиться как то так:
Далее
- Загружаем скетч в arduino
- Открываем мониторинг порта (выбираем настройки 115200...) и вбиваем простые команды "START", "GET CHIPID", "READ FLASH"
Должны увидеть:
Мы видим, что основные команды работают программатора, поэтому приступаем к части на Python.
3. Программа на python
import serial
import time
# Настраиваем COM порт для взаимодействия с программатором
port = "COM4" # Это COM port к которому подключен arduin
baudrate = 115200 # Ставим максимальную скорость com порта
ser = serial.Serial(port, baudrate=baudrate) # Создали объект серийного порта
ser.baudrate = 115200 # set Baud rate to 115200
ser.bytesize = 8 # Number of data bits = 8
ser.parity ='N' # No parity
ser.stopbits = 1 # Number of Stop bits = 1
time.sleep(3) # без задержки иногда зависало
fh = open('data.hex','w') # Создаем файл для записи hex файла (можно убрать)
fb = open('data.bin','bw') # Для сохранения прошивки в бинарном формате
message = b"START" # Данные в com port отправляем в байтовом виде, поэтому ставим перед строкой b
ser.write(message) # Отправляем команду START в программатор
line = ser.readline().decode() # Ответ программатора
print(line) # прочитаем ответ - там будет информация
line = ser.readline().decode() # о чипе cc2541
print(line) # несколько строк
line = ser.readline().decode()
print(line)
ser.write(b'READ FLASH') # отправляем команду считывания прошивки
line = ser.readline().decode() # Это строки , которые выводят инф красиво
line = ser.readline().decode() # если запускать из терминала порта
for j in range(0,512): # Мы читаем 512 блоков по 512 байт циклами
for i in range(0,512):
line = ser.readline().decode() # Читаем строку в которой 1 байт прошивки
fh.write(line) # пишем эту строку в файл (формат addr: code hex, code dec)
fb.write( int(line[-5:]).to_bytes(1,byteorder='big')) # берем только код и пишем
print(j) # выводим на экран номер блока - так наблюдаем за процессом
ser.write(b'NEXT') # даем команду программатору выдать следующий блок
fh.close() # Закрываем файлы
fb.close()
ser.close() # и закрываем порт
4. Подключаем и считываем прошивку
Не забываем в python поставить правильный порт и закрыть окно мониторинга последовательного пората в arduino IDE.
Запускаем....
дожидаемся дохода до 511 (так как начинаем отсчет с 0, а не с 1, поэтому 511, а не 512)
5. Проверяем прошивку
Вид файлов с прошивкой.
Я прошивал прошивку и считывал несколько раз из контроллера 100% совпадение.
Выводы
Всегда перед прошивкой контроллера считываем прошивку, что бы в случае неудачной прошивки вернуть все в исходное состояние.
Познакомились с протоколом debug микроконтроллера cc2541.
Просьба
Так как я пока еще не закончил эксперименты и не купил второй такой де контроллер, что бы считать с него прошивку, то большая просьба, если Вы решите перепрошить свой bluetooth модуль, то считайте прошивку с него и пришлите, ну или самостоятельно выложите её всеобщее обозрения. Многие будут Вам благодарны.
Спасибо.