Раскирпичиваем NIIMBOT B21_C2B

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

И один из них - восстановление работоспособности после неудачной прошивки.

⚠️ ВНИМАНИЕ! ВЫПОЛНЯЙТЕ ЭТИ ДЕЙСТВИЯ НА СВОЙ СТРАХ И РИСК!

Данная процедура приведёт к безвозвратной потере заводских данных принтера (серийный номер, MAC-адрес и т.д.).

Штатное обновление прошивки станет невозможным.

Печать через официальное приложение вероятно станет невозможной из-за невалидного серийного номера.

Есть риск превратить устройство в кирпич, если оно им ещё не стало.

Данная инструкция написана для аппаратной версии 40.10. Для других версий шаги и файлы могут отличаться. Прошивки для разных аппаратных версий не совместимы между собой.

О прошивке под данный принтер

Принтер работает на микроконтроллере Artery AT32F403ARCT7. Прошивка состоит из нескольких частей:

  1. 0x00000000 - загрузчик (bootloader)
  2. 0x08002000 - основная часть
  3. 0x0803f000 - участок с серийным номером, mac адресом и прочих данных, привязанных к каждому принтеру

Основная часть прошивки

Касаемо основной части всё просто. Она обновляется официальным приложением по Bluetooth или USB. В открытом доступе не публикуются, но через API я собрал все доступные прошивки тут.

Грузится прошивка не с нулевого адреса, так как присутствует загрузчик. Определить базовый адрес проще всего оказалось с помощью Binary Ninja через Triage View. Утилиты basefind/rbasefind/binbloom или зависали, или показывали какую-то чушь.

ninja_base

Загрузчик

Вот тут начинаются проблемы. Загрузчика для данного принтера вообще ни в каком виде не найти.

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

Остаётся последний вариант - сделать свой загрузчик.

Со страницы Artery для чипа AT32F403A взял всё необходимое: пак для Keil и шаблоны проектов. Процесс подготовки рабочего окружения описывать не буду, так как текста про это выйдет размером с новую статью.

Загрузчик будет максимально простым. Нужно просто передать управление пользовательской программе по адресу 0x08002000.

Оригинальный загрузчик также выполняет операцию по обновлению прошивки по USB/Bluetooth, но реализовать такое с нуля, не зная того как это делалось, я не осилю.

В итоге получился вот такой код:

#include "at32f403a_407.h"

#define APP_ADDRESS  0x08002000

typedef void (*pFunction)(void);

void jump_to_app(void)
{
    uint32_t appStack = *(__IO uint32_t*)APP_ADDRESS;
    pFunction appEntry = (pFunction)*(__IO uint32_t*)(APP_ADDRESS + 4);

    if ((appStack & 0x2FFE0000) == 0x20000000)  // Check for valid RAM address
    {
        __disable_irq();
        SCB->VTOR = APP_ADDRESS;
        __set_MSP(appStack);
        __enable_irq();
        appEntry();
    }
}

int main(void)
{
    jump_to_app();

    while (1)
    {}
}

Скомпилированный загрузчик: AT32F403A_bootloader_min.hex

Участок с уникальными данными принтера

Структура неизвестна.

Этот участок пострадает при снятии защиты микроконтроллера. В лучшем случае принтер станет думать, что его серийный номер состоит из единиц.

Перевод микроконтроллера в режим прошивки

Как оказалось, для программирования данного микроконтроллера совсем не обязательно покупать программатор. Достаточно перевести его в режим USB DFU и прошивка станет доступна через USB порт принтера.

Для перевода микроконтроллера в режим USB DFU нужно чтобы во время включения на пине BOOT0 был высокий логический уровень.

AT32F403A_LQFP64
AT32F403ARCT7

На плате изначально он подтянут к нулю через 10к резистор. Я подключил BOOT0 к 3v3 через 1к резистор. Можно и напрямую.

При наличии микроскопа или хорошего зрения можно подпаяться прямо к ножке микроконтроллера. Я так и сделал. Так даже не придётся вынимать плату из принтера.

pcb_top_boot

С другой стороны платы выведен тестпоинт с BOOT0, можно использовать и его.

pcb_bottom_boot

Снятие защиты микроконтроллера

Программатор скачивается тут. Называется Artery ISP Programmer. В конце статьи есть копия архива.

Устанавливаем драйвер, запускаем программатор. В программаторе нужно выбрать тип порта USB DFU. В списке должен появиться микроконтроллер.

ArteryISPProgrammer_connect

Далее открывается обзор блоков. Как видим, все они защищены от доступа. Эту защиту нужно снять.

ArteryISPProgrammer_blocks

Выбираем режим Protection.

ArteryISPProgrammer_blocks_erase1

⚠️ ТОЧКА НЕВОЗВРАТА

После подтверждения принтер станет полностью неработоспособным, если до этого он подавал хоть какие-то признаки жизни.

ArteryISPProgrammer_blocks_erase2

Загрузка программы

Снова подключаемся к микроконтроллеру. Выбираем режим Download to device.

  1. Нажимаем Add и выбираем загрузчик AT32F403A_bootloader_min.hex.

  2. Нажимаем Add и выбираем прошивку B21-C2B_40.19.bin.

Это актуально только для аппаратной версии принтера 40.x. Для других версий нужна другая прошивка (stable / testing). Мажорная версия прошивки и аппаратной версии должны совпадать (например, для аппаратной 12.01 должна подойти любая 12.x).

Начальный адрес выбираем 08002000.

ArteryISPProgrammer_blocks_addr

Ставим галочку Jump to user program чтобы принтер сразу выполнил свою программу после перепрошивки. Иначе придётся снимать перемычку и переподключать USB.

ArteryISPProgrammer_prog

Запускаем процесс.

ArteryISPProgrammer_flashing

В конце принтер сразу определится компьютером и начнёт мигать светодиодом.

newdevice

В целом всё. Из побочных эффектов можно отметить невозможность дальнейшей перепрошивки штатными средствами. Из официального приложения скорее всего печатать не получится ввиду проблем с серийным номером.

printerinfo

Поэтому, привет NiimBlue.

Прочее

Информация о железе других принтеров

Копии файлов с сайта Artery:

DS_AT32F403A_V2.04_EN.pdf (даташит)

Artery_ISP_Programmer_V2.0.17.zip (программатор)

Keil5_AT32MCU_AddOn_V2.4.6.zip (паки для Keil)