Найти в Дзене

Считываем прошивку из Bluetooth MLT-BT05

Оглавление

Практика говорит, что всегда прежде чем прошить в контроллер что-то новое, сделайте резервную копию текущей прошивке. В один прекрасный момент я сделал программатор тут, но не смог найти готовый софт для считывания прошивки для контроллера cc2541 (bluetooth модуль MLT-BT05) и решил на свой страх и риск залить в него новую прошивку. Результат ожидаемый - модуль не работает.

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

План

1. Разбираемся с командами режима debug сс2542

2. Модифицировать arduino скетч из моей статьи. Arduino будет в роли программатора

3. Написать программу на Python (взамен CCLoader) с помощью которой будем отправлять команды на программатор и сохранять файл с прошивкой на компьютер.

4. Все подключить и считать прошивку

5. Проверить корректность

1. Режим debug сс2541

В режиме отладки контроллер может принимать команды в основном длиной от 1 до 4 байт, кроме команд блочной записи и чтения (2025байт).

Команда = код команды + байты с данными для команды

В ответ котроллер высылает байты с результатом.

Цикл отправки команды и получения результата через порты P1_1  и P1_2
Цикл отправки команды и получения результата через порты P1_1 и P1_2

Lлину команд на отправку и количество получаемых данных можно увидеть в таблице:

-2

Как видим команда получения идентификатора чипа 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"
-4

Должны увидеть:

Мы видим, что основные команды работают программатора, поэтому приступаем к части на 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.

Запускаем....

-6

дожидаемся дохода до 511 (так как начинаем отсчет с 0, а не с 1, поэтому 511, а не 512)

5. Проверяем прошивку

Вид файлов с прошивкой.

-7

Я прошивал прошивку и считывал несколько раз из контроллера 100% совпадение.

Выводы

Всегда перед прошивкой контроллера считываем прошивку, что бы в случае неудачной прошивки вернуть все в исходное состояние.

Познакомились с протоколом debug микроконтроллера cc2541.

Просьба

Так как я пока еще не закончил эксперименты и не купил второй такой де контроллер, что бы считать с него прошивку, то большая просьба, если Вы решите перепрошить свой bluetooth модуль, то считайте прошивку с него и пришлите, ну или самостоятельно выложите её всеобщее обозрения. Многие будут Вам благодарны.

Спасибо.