База знаний · Сборка и прошивка

Программатор и загрузчик: прошивка в обход USB

Что такое загрузчик, сколько места он занимает, когда без программатора не обойтись и как прошить плату через разъём ICSP.

Обычно скетч попадает в плату по USB — и внутри платы его встречает маленькая программа-привратник, загрузчик. Программатор нужен там, где привратника нет: в чистой микросхеме, в плате после неудачного эксперимента, в ATtiny без всякого USB. Разберём обе дороги и то, что между ними.

Что такое загрузчик и сколько он стоит

Загрузчик — это программа, которая живёт в самом конце флеш-памяти микроконтроллера и запускается первой после сброса. Если сброс был внешним, она секунду слушает порт: не пришлют ли новую прошивку. Не пришли — управление уходит вашему скетчу. (Почему «если внешним» — чуть ниже, это важнее, чем кажется.)

Живёт он в конце не из вежливости. Команда процессора, которой можно писать во флеш-память, физически работает только из этой особой области — из обычной программы она просто отключена. Поэтому записать скетч сам в себя чип не может, а загрузчик — может.

Флеш-память ATmega328P — 32 768 байтваш скетч032 768загрузчик optibootфайл — 502 байта, места отведено 512скетчу доступно 32 256 байтЗаливка по USB работает. Скетчу достаётся 32 256 байт из 32 768.
Загрузчик живёт в самом конце флеша и стоит недорого: на Uno это полкилобайта из тридцати двух. Nano резервирует под него 2 КБ — так записано в заводских настройках чипа, и полтора килобайта там просто пропадают.

Мы разобрали настоящие файлы загрузчиков из ядра Arduino и посчитали байты. Optiboot для ATmega328P — 502 байта, и он занимает адреса с 32 256-го по 32 767-й. Старый загрузчик, который до сих пор стоит в дешёвых Nano, — 1 950 байт.

ПлатаВсего флешаСвободно скетчуУходит загрузчикуПочему так
Arduino Uno32 76832 256512 байтOptiboot, самый экономный
Arduino Nano32 76830 7202 048 байтРезерв остался от старого загрузчика
Arduino Pro Mini32 76830 7202 048 байтЗдесь старый загрузчик и правда стоит
Arduino Leonardo32 76828 6724 096 байтЗагрузчик Caterina сам держит USB
Arduino Mega 2560262 144253 9528 192 байтаДругой протокол, другой загрузчик

В строчке про Nano спрятана обидная мелочь. Файл загрузчика там сегодня тот же самый, что у Uno, — 502 байта. А места под него заводские настройки чипа резервируют 2 048. Полтора килобайта флеша просто пропадают, и виноват не производитель платы, а строчка в описании Arduino, которую не поправили с давних времён. У Pro Mini та же строчка честная: там в описании до сих пор прописан старый загрузчик на 1 950 байт, и резерв занят почти целиком.

Почему плата моргает не всегда

Расхожее объяснение звучит так: «после сброса загрузчик секунду ждёт прошивку и мигает светодиодом». Это верно наполовину. Optiboot первым делом смотрит, отчего случился сброс, и ждёт только в одном случае — если сброс был внешний: нажали кнопку RESET или компьютер дёрнул линию сброса, начиная заливку.

При подаче питания, при просадке напряжения и при сбросе от сторожевого таймера загрузчик не ждёт и не мигает вовсе — скетч стартует сразу. Отсюда и наблюдение, которое многих сбивает с толку: воткнул питание — плата заработала мгновенно, нажал RESET — она задумалась и трижды мигнула.

Ещё три вещи из исходника, которые полезно знать:

  • Секунда — это таймаут между байтами, а не общий лимит на прошивку. Пока данные идут, загрузчик ждёт сколько угодно.
  • Если байт пришёл искажённым (скорость не та), Optiboot нарочно не сбрасывает свой сторожевой таймер и через секунду уходит в скетч. Так плата не зависает, когда в порт «говорят» не на том языке.
  • Заявленные 115 200 бод на самом деле 117 647 — делитель на 16 МГц ровно в эту скорость не попадает. Ошибка около двух процентов, приёму она не мешает.

И одно ограничение: Optiboot умеет писать только флеш. Работать с EEPROM он не умеет вовсе, хотя старый загрузчик это когда-то умел.

Когда без программатора не обойтись

СлучайЧто происходит
Загрузчика нет вовсеМикросхема, купленная отдельно, приходит с завода пустой
Загрузчик стёрсяПосле прошивки через программатор или неудачного эксперимента с фьюзами
Плата молчит по USBПрограмматор говорит с чипом напрямую и покажет, живой он или нет
Нужен весь флешПрошивка через программатор не оставляет места загрузчику
Микросхема без USBATtiny, самоделка на макетке, плата с одним только разъёмом ICSP
Надо поменять фьюзыЧастота, сторожевой таймер, порог питания — по USB туда не добраться

Разъём ICSP

Программатор говорит с чипом не через USB, а по четырём проводам: такт, данные туда, данные обратно и сброс. Плюс питание и земля. Эти шесть контактов и собраны в гребёнку 2×3, которую на платах Arduino подписывают ICSP.

Разъём ICSP, вид сверху1MISO2+5 В3SCK4MOSI5RESET6GNDвывод 1 помечен на плате точкой или квадратной площадкойНа Uno два таких разъёмаICSP у большой микросхемы — рабочий. Разъём ICSP1 у гнезда USBпринадлежит мосту ATmega16U2 — ваш скетч туда не пишется.
Порядок контактов одинаков у всех плат AVR: 1 — MISO, 2 — питание, 3 — SCK, 4 — MOSI, 5 — RESET, 6 — земля. На Uno эти же сигналы выведены на цифровые 12, 13 и 11, поэтому программатор можно подключить и туда. На Mega 2560 они тоже на колодках, но в другом месте — 50, 51 и 52. У Leonardo и Micro на колодках их нет: только гребёнка.

На Uno и Nano те же три сигнала выведены и на цифровые выводы 11, 12 и 13 — это видно прямо в схеме платы, где ножки микросхемы подписаны MOSI, MISO и SCK. Поэтому подключаться можно куда удобнее.

На других платах схема «11 к 11, 12 к 12, 13 к 13» не повторится. У Mega 2560 те же сигналы просто живут в другом месте: MISO — вывод 50, MOSI — 51, SCK — 52. А у Leonardo и Micro их на колодках нет вовсе, остаётся только гребёнка ICSP.

Чем прошивать

ПрограмматорЦена вопросаОсобенности
Arduino as ISPбесплатно, нужна вторая платаШтатный режим. Скорость 19 200, протокол stk500v1
USBaspсамый дешёвый готовыйТребует драйвера в Windows и перемычки для медленных целей
USBtinyISPнедорогой готовыйПроще с драйверами, но не умеет чипы с флешем больше 64 КБ
AVRISP mkII, Atmel-ICEфирменныеБыстрые и без сюрпризов, но стоят как несколько плат

Список в программе берётся не из воздуха: он читается из файла описаний, который приходит вместе с пакетом поддержки плат. Там же спрятана ловушка, на которой спотыкаются все. В списке есть два похожих пункта: «ArduinoISP» и «Arduino as ISP» (а рядом ещё и «ArduinoISP.org»). Второй пришедшей плате со скетчем соответствует только один — «Arduino as ISP». Первый — это отдельное фирменное устройство, и разговаривает программа с ним по другому протоколу.

Arduino as ISP: пять шагов

Самый доступный программатор — вторая плата Arduino. Порядок действий важен: если сделать шаги 1 и 2 наоборот, ничего не получится.

ПРОГРАММАТОРUno со скетчем ArduinoISPПОДОПЫТНАЯ ПЛАТАили голый ATmega328P10сбросRESET11MOSI11 (MOSI)12MISO12 (MISO)13SCK13 (SCK)5V5 В5VGNDGNDGNDданные в подопытную плату
Шесть проводов — и ни одним больше. Седьмая деталь не провод: конденсатор около 10 мкФ между RESET и GND платы-программатора. Он не даёт компьютеру перезапустить сам программатор в тот момент, когда тот занят прошивкой соседа.
  1. Залейте в плату-донора скетч ArduinoISP — он есть во встроенных примерах. Обычная заливка по USB, ничего особенного.
  2. Теперь поставьте конденсатор около 10 мкФ между выводами RESET и GND донора, длинной ногой к RESET. Он гасит импульс сброса, которым компьютер дёргает плату при подключении, — иначе донор будет сбрасываться сам в разгар работы. Ставить его до заливки нельзя: тем же импульсом заливается и сам ArduinoISP.
  3. Соедините шесть проводов по схеме выше. Общая земля обязательна всегда, а вот 5 вольт нужны только если подопытную плату нечем питать отдельно.
  4. В программе выберите ЦЕЛЕВУЮ плату — ту, которую прошиваете, а не донора. Порт при этом — порт донора. Это второе место, где ошибаются чаще всего.
  5. Нажмите «Записать загрузчик» и дождитесь конца.

Полезная мелочь для тех, кто прошивает часто. Скетч ArduinoISP умеет показывать, что происходит, тремя светодиодами: на выводе 9 — ровное «дыхание», значит программатор жив; на выводе 8 — ошибка; на выводе 7 — идёт обмен с целью. На готовой плате этих светодиодов нет, их надо повесить самому, каждый через резистор.

Донором может быть и Leonardo или Micro — у них USB встроен прямо в микроконтроллер. Тогда конденсатор не нужен вовсе, зато появляются два отличия: в списке программаторов надо выбрать отдельный пункт «Arduino as ISP (ATmega32U4)», а три провода данных брать не с выводов 11, 12 и 13 — у этих плат там ничего нет, — а с их собственной гребёнки ICSP. Провод сброса по-прежнему идёт с вывода 10.

USBasp: дешёвый и с характером

Готовый программатор за небольшие деньги, придуманный Томасом Фишлем. Работает надёжно, но у него две особенности, из-за которых новички считают его неисправным.

Первая — скорость. USBasp по умолчанию тактует чип на 375 килогерцах, и поменять это старая прошивка не умеет. Правило же такое: такт программатора должен быть как минимум вчетверо ниже собственной частоты микросхемы. А новая ATmega328P из пакетика работает не на 16 мегагерцах, а на одном: с завода она тактуется внутренним генератором с включённым делителем. Предел для неё — 250 килогерц, то есть медленнее, чем даёт USBasp. Отсюда знаменитое Device signature = 0x000000 на совершенно исправном чипе. Лечится перемычкой «Slow SCK» на самом программаторе — она роняет такт до 8 килогерц.

Вторая — предупреждение. Почти каждый USBasp при каждом запуске печатает warning: cannot set sck period. Это не поломка: программа просит программатор сменить скорость, а прошивка такой команды не знает и не отвечает. Avrdude это видит, но фатальной ошибкой не считает — печатает предупреждение и спокойно продолжает прошивать.

В Windows USBasp ещё требует драйвера — своего, не системного. Он входит в комплект программатора; если система его не видит, драйвер ставят вручную.

Как это делается в Trema IDE

Всё описанное встроено в среду, отдельные программы запускать не надо. В верхней панели появляется кнопка «Программатор», а в ней — выбор программатора и две команды: «Загрузить через программатор» и «Записать загрузчик».

Кнопки может не быть, и это нормально. Чтобы она появилась, нужны три вещи сразу: открытый проект, выбранная плата, работающая через пакет поддержки Arduino, и найденный в этом пакете список программаторов. У встроенных плат, которые собираются движком PlatformIO, программаторов нет вовсе — там и выбирать нечего.

«Записать загрузчик» выполняет две команды подряд. Первая стирает чип целиком и заново записывает три байта заводских настроек, сняв блокировку. Вторая заливает файл загрузчика и ставит защиту, чтобы скетч не мог затереть загрузчик сам. Для Uno через вторую Arduino это выглядит так:

avrdude -patmega328p -cstk500v1 -PCOM3 -b19200 -e \
        -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m

avrdude -patmega328p -cstk500v1 -PCOM3 -b19200 \
        -Uflash:w:optiboot_atmega328.hex:i -Ulock:w:0x0F:m

Слово «стирает целиком» стоит понимать буквально: у Uno заводские настройки не велят беречь энергонезависимую память, поэтому сохранённые в EEPROM данные тоже пропадут. Если там лежат настройки устройства, их надо сохранить заранее.

Фьюзы: три байта, которыми можно убить плату

Фьюзы — это заводские настройки самой микросхемы, три байта: откуда брать такт, при каком напряжении уходить в сброс, сколько места отвести загрузчику, работает ли вообще разъём программатора. Скетч их не видит и поменять не может — только программатор.

Именно из этих байтов растёт разница между Uno и Nano, о которой шла речь выше: одинаковый чип, одинаковый загрузчик, но у Uno под него отведено 512 байт, а у Nano — 2 048. Одна пара битов.

Что сделалиЧто получилосьКак чинить
Выбрана плата с кварцем, а кварца нетЧип замолкает навсегда — он ждёт такта снаружиПодать такт на вывод XTAL1 от другой платы или припаять кварц
Выключен бит SPIENПрограмматор больше не может достучаться до чипаСлучайно не сделать: обычному программатору этот бит недоступен
Включён бит RSTDISBLВывод RESET становится обычным выводом, сброса больше нетТо же самое: высоковольтный программатор
Поставлены биты блокировкиПрошивку не прочитать и не перезаписатьЛечится обычным стиранием чипа: биты блокировки снимаются вместе с ним

Обратите внимание на последнюю строку. Биты блокировки, которых все боятся, кирпичом плату не делают: они снимаются обычным стиранием чипа. А вот фьюзы стирание не трогает — и вот они опасны по-настоящему.

Самая частая беда — первая строка таблицы. Человек собирает плату на макетке из голой микросхемы без кварца, а в меню выбирает «Arduino Uno». Записывается настройка «такт брать снаружи», кварца снаружи нет, и микросхема замолкает навсегда. Ни программатор, ни USB её больше не достанут, пока не подать такт извне.

Тут есть неприятная тонкость. В штатном пакете Arduino AVR нет ни одного пункта для ATmega328 без кварца: даже «ATmega328P (3.3V, 8 MHz)» рассчитан на внешний резонатор. Пункт с внутренним генератором приходит только со сторонним пакетом плат. Взять похожий на вид штатный пункт — верный способ получить как раз молчащий чип.

Прошивка через программатор: скетч без загрузчика

Команда «Загрузить через программатор» сначала собирает скетч, а потом заливает его в чип напрямую. Полезно, когда загрузчик не нужен: скетчу достаётся весь флеш целиком, и после нажатия RESET плата стартует сразу, без секундной паузы (при подаче питания её, как мы выяснили выше, не было и так).

Плата за это ровно одна, и она предсказуема: загрузчик при этом стирается. По USB плата больше не прошивается — не тем, что сломалась, а тем, что разговаривать о прошивке ей теперь нечем. Возврат в исходное состояние — одно нажатие «Записать загрузчик» тем же программатором. После этого стоит убедиться, что всё живо, обычным скетчем:

void setup() {
  // Настраиваем вывод со встроенным светодиодом на выход.
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // подали напряжение — светодиод горит
  delay(500);                       // ждём полсекунды
  digitalWrite(LED_BUILTIN, LOW);   // сняли напряжение — светодиод погас
  delay(500);                       // и снова ждём полсекунды
}

HEX-файл: готовая прошивка без исходников

Результат сборки — файл с расширением .hex. Внутри обычный текст: каждая строка начинается с двоеточия, дальше идёт длина, адрес, тип записи, сами данные и контрольная сумма. Из-за этого файл весит примерно вдвое-втрое больше самой прошивки, зато его можно переслать письмом и залить где угодно.

Заливается он одной командой, без всякой компиляции:

avrdude -patmega328p -carduino -PCOM3 -b115200 -Uflash:w:sketch.hex:i

Ключ -c задаёт способ связи: arduino — через загрузчик по USB, stk500v1 или usbasp — через программатор. Обратная операция тоже возможна — прошивку можно вычитать из платы в файл, если предыдущий владелец не поставил биты блокировки.

Голый чип на макетке

Самодельная Arduino — это микросхема, питание, кварц 16 МГц с двумя конденсаторами по 22 пФ и резистор 10 кОм от вывода RESET к плюсу. Официальная инструкция Arduino допускает и вариант вообще без кварца: тогда чип работает от внутреннего генератора на 8 МГц, но его точность около ±10 %. Для такой сборки понадобится сторонний пакет плат — в штатном подходящего пункта нет.

Три вещи, на которых спотыкаются:

  • Номер ножки микросхемы не равен номеру вывода Arduino. Тринадцатая ножка корпуса — это вывод 7, а вывод 13 сидит на девятнадцатой ножке.
  • ATmega328 и ATmega328P — разные микросхемы с разными подписями. Программа честно остановится и скажет, что подпись не совпала.
  • Кварц на 16 МГц требует питания около четырёх вольт и выше. На 3,3 вольта та же схема работать по паспорту не обязана — это частая причина «необъяснимых глюков» самоделок.

Для ATtiny всё то же самое, только меню плат надо сначала пополнить сторонним пакетом. И там кнопка «Записать загрузчик» нужна даже тогда, когда никакого загрузчика не хочется: она заодно прописывает частоту, а с завода ATtiny работает на одном мегагерце.

У ESP всё устроено иначе

Для ESP8266 и ESP32 вопрос «как прошить загрузчик» не имеет смысла. Первая ступень у них зашита в кремний на заводе — её нельзя ни стереть, ни испортить, ни перезаписать. Разъёма ICSP у них тоже нет.

В режим прошивки эти платы входят иначе: один определённый вывод прижимается к земле в момент сброса. На готовых платах вроде NodeMCU это делает схема на самом USB-мосте, поэтому кнопки нажимать не надо. Прошивает их не avrdude, а своя программа, и она приходит вместе с пакетом поддержки платы.

Приятное следствие: окирпичить ESP неудачной прошивкой практически невозможно. Что бы вы туда ни залили, заводская ступень остаётся на месте и всегда готова принять новую прошивку.

Что делать, если не получается

Что написаноЧто это значитЧто делать
Device signature = 0x000000Программатор вообще не слышит чипПроверить провода и питание. Если цель с завода — включить медленный SCK
Expected signature for ATmega328PВ чипе стоит ATmega328 без буквы P — у него другая подписьНужен сторонний пакет плат, где такой чип есть отдельным пунктом
warning: cannot set sck periodСтарая прошивка USBasp не знает команду смены скоростиНичего не делать: прошивка идёт как обычно
not in sync / programmer is not respondingОбе жалобы про одно: ответа от программатора нетПроверить порт и пункт программатора; на Uno-доноре — конденсатор
Кнопки «Программатор» нет в панелиНет открытого проекта, или у платы нет пакета поддержки ArduinoОткрыть проект и выбрать плату из установленного пакета

Если плата не прошивается по обычному USB и до программатора дело ещё не дошло — начните с разбора ошибки при загрузке: в девяти случаях из десяти дело в порте, драйвере или старом загрузчике у Nano, а не в стёртом загрузчике.

Частые вопросы

Что такое загрузчик Arduino?

Маленькая программа, которая живёт в конце флеш-памяти микроконтроллера и запускается первой после каждого сброса. Если сброс был внешним — нажали RESET или компьютер начал заливку, — она примерно секунду слушает порт: не пришлют ли новую прошивку. При обычной подаче питания ждать не станет и сразу передаст управление скетчу. Именно загрузчик делает Arduino Arduino: без него плату пришлось бы прошивать отдельным устройством. Файл optiboot для ATmega328P занимает 502 байта — мы измерили его прямо в ядре.

Зачем нужен программатор, если есть USB?

Пять случаев. Загрузчик стёрся или его не было изначально (голый чип из магазина). Плата не отвечает по USB, и нужно понять — умерла она или дело в загрузчике. Нужен весь флеш до последнего байта. Нужно прошить микроконтроллер без USB вовсе — ATtiny, самодельную плату на макетке. И наконец, нужно поменять заводские настройки чипа — те самые фьюзы, до которых по USB не добраться.

Можно ли использовать Arduino как программатор?

Да, это штатный режим и называется он «Arduino as ISP». Нужна вторая плата, встроенный пример ArduinoISP и шесть проводов: 10 к сбросу подопытной платы, 11 к 11, 12 к 12, 13 к 13, плюс питание и земля. Ещё нужен конденсатор около 10 мкФ между RESET и GND платы-программатора — иначе компьютер будет сбрасывать её в момент работы. В списке программаторов выбирать нужно именно «Arduino as ISP», а не похожий пункт «ArduinoISP»: у них разные протоколы.

Что делает кнопка «Записать загрузчик»?

Две операции подряд, обе через программатор. Сначала стирается вся флеш-память и заново записываются три байта заводских настроек — фьюзов, а заодно снимается блокировка. Потом в чип заливается файл загрузчика и ставятся защитные биты, чтобы скетч не смог затереть загрузчик сам. Всё это Trema IDE берёт из описания платы, ничего вручную указывать не нужно.

Почему после программатора плата не прошивается по USB?

Потому что загрузчика больше нет. Заливка через программатор пишет скетч с нулевого адреса и стирает всё остальное, включая загрузчик в конце памяти. Плата при этом полностью рабочая — просто разговаривать по USB о прошивке ей теперь нечем. Лечится одним нажатием: «Записать загрузчик» тем же программатором.

Как залить в плату готовый HEX-файл без исходников?

HEX — это текстовый файл с готовой прошивкой, его можно залить программой avrdude напрямую, без компиляции. Команда выглядит так: avrdude -p atmega328p -c arduino -P COM3 -b 115200 -U flash:w:файл.hex:i. Ключ -c задаёт способ связи (arduino — через загрузчик, usbasp или stk500v1 — через программатор), -P порт, -b скорость. Обратная операция, чтение прошивки из платы, работает только если чип не заблокирован защитными битами.

Нужно ли прошивать загрузчик в ESP8266 и ESP32?

Нет, и не получится. У этих чипов загрузчик зашит в кремний на заводе и стереть его нельзя в принципе. В режим прошивки они входят иначе: вывод GPIO0 прижимается к земле в момент сброса, а на готовых платах вроде NodeMCU это делает схема на линиях DTR и RTS самого USB-моста. Прошивает их не avrdude, а esptool.

Обновлено: 25 августа 2026