Что происходит, когда код загружается с помощью загрузчика?
Что на самом деле происходит, когда я загружаю новый скетч в Arduino Uno с помощью загрузчика Optiboot?
- Что отправляется на Arduino?
- Как он реагирует?
- Что означает «не синхронизировано»?
- Что вообще такое «синхронизировать»?
Примечание. Это «справочный вопрос».
@Nick Gammon, 👍15
Обсуждение1 ответ
Лучший ответ:
При сбросе настроек Uno с запущенным загрузчиком Optiboot загрузчик сначала трижды мигает на контакте 13.
Верхняя линия (серая) отправляется на Arduino, средняя линия (оранжевая) отправляется с Arduino.
В это время программа avrdude
, запущенная на вашем компьютере, отправляет запрос на устройство:
STK_GET_SYNC / CRC_EOP (0x30/0x20)
Arduino не замечает первую «get sync», потому что она занята миганием контакта 13. Как только это сделано, она замечает «get sync» (она будет буферизована последовательным оборудованием) и отвечает:
STK_INSYNC / STK_OK (0x14/0x10)
Похоже, avrdude немного нетерпелив и истекло время ожидания, потому что он снова пытается сделать запрос "get sync". На этот раз Optiboot отвечает немедленно.
Остальная часть загрузки описана на следующем изображении. Пример, полученный при загрузке стандартной программы "Blink".
(Нажмите на изображение выше, чтобы увеличить его)
Шаги следующие:
- Запрос: Получить синхронизацию? Ответ: Синхронизировано.
- Запрос: Получить параметр? (основная версия) Ответ: версия 4.
- Запрос: Получить параметр? (дополнительная версия) Ответ: версия 4.
Установить параметры устройства. Следующие параметры устройства отправляются на чип:
0x42 // STK_SET_DEVICE 0x86 // код устройства 0x00 // ревизия 0x00 // progtype: «0» – как параллельный/высоковольтный, так и последовательный режим 0x01 // parmode: «1» – Полный параллельный интерфейс 0x01 // опрос: «1» — опрос может быть использован 0x01 // самосинхронизированный: «1» – самосинхронизированный 0x01 // lockbytes: Количество байтов блокировки. 0x03 // fusebytes: Количество байтов Fuse 0xFF // flashpollval1 0xFF // flashpollval2 0xFF // eeprompollval1 0xFF // eeprompollval2 0x00 // pagesizehigh 0x80 // размер_страницы_низкий 0x04 // eepromsizehigh 0x00 // eepromsizelow 0x00 // flashsize4 0x00 // размер_флэша3 0x80 // размер_флэша2 0x00 // размер_флэша1 0x20 // Sync_CRC_EOP
Optiboot игнорирует все это и отвечает In Sync/OK. :)
Установите расширенные параметры устройства:
0x45 // STK_SET_DEVICE_EXT 0x05 // commandsize: сколько байт следует 0x04 // eeprompagesize: размер страницы EEPROM в байтах. 0xD7 // сигнальная страница: 0xC2 // сигналы2: 0x00 // ResetDisable: определяет, имеет ли деталь предохранитель RSTDSBL 0x20 // Sync_CRC_EOP
Optiboot все это игнорирует и отвечает In Sync/OK.
Вход в режим программирования. Ответ: Синхронизация/ОК.
Прочитать подпись. Optiboot отвечает
0x1E 0x95 0x0F
фактически не читая подпись.Запись предохранителей (четыре раза). Optiboot не записывает предохранители, а просто отвечает In Sync/OK.
Загрузить адрес (изначально 0x0000). Адрес в словах (т.е. слово — это два байта). Это устанавливает адрес, куда будет записана следующая страница данных.
Программная страница (отправляется до 128 байт). Optiboot немедленно отвечает «In Sync». Затем следует пауза около 4 мс, пока он фактически программирует страницу. Затем он отвечает «OK».
Адрес загрузки (теперь 0x0040). Это адрес 64 в десятичном виде, т.е. 128 байт от начала памяти программ.
Пишется еще одна страница. Эта последовательность продолжается до тех пор, пока не будут написаны все страницы.
Загрузить адрес (обратно к 0x0000). Это для проверки записи.
Прочитать страницу (считывается до 128 байт). Это для проверки. Обратите внимание, что даже если проверка не удалась, плохие данные уже записаны в чип.
Выйти из режима программирования.
Что означает «не синхронизировано»?
Как вы можете видеть из вышесказанного, на каждом шаге последовательности программирования Arduino должен отвечать «In Sync» (0x14), возможно, за которым следуют какие-то данные, а затем «OK» (0x10).
Если это "не синхронизировано", это означает, что avrdude не получил ответ "синхронизировано". Возможные причины:
- Использована неправильная скорость передачи данных
- В IDE выбран неправильный последовательный порт
- В IDE выбран неверный тип платы
- Загрузчик не установлен
- Установлен неправильный загрузчик
- Плата не настроена на использование загрузчика (в предохранителях)
- Какое-то устройство, подключенное к контактам D0 и D1 на Arduino, мешает последовательной связи
- Микросхема интерфейса USB (ATmega16U2) работает неправильно
- Неправильные часы для доски
- Неправильные настройки предохранителей на Atmega328P (например, «делить тактовую частоту на 8»)
- Плата/чип повреждены
- Неисправный USB-кабель (некоторые USB-кабели обеспечивают только питание и не предназначены для передачи данных, например дешевые кабели для USB-вентиляторов)
Что такое «синхронизировано»?
Как уже упоминалось выше, ответ «Синхронизирован» означает, что Arduino (загрузчик) синхронизирован с загружаемой программой.
Какой протокол используется?
Протокол — это протокол STK500, документированный Atmel. См. ссылки ниже.
Ссылки
- Исходный код Optiboot - GitHub
- AVR061: протокол связи STK500
- AVR068: Протокол связи STK500 версии 2
- Я сломал свой Arduino Uno? Проблемы с загрузкой на плату
- Загрузчик/выгрузчик AVR - avrdude
Примечание: STK500 версии 2 не используется в Optiboot, но включена для информации на случай, если вы используете такие платы, как Mega2560.
Константы STK500
/* STK500 constants list, from AVRDUDE */
#define STK_OK 0x10
#define STK_FAILED 0x11 // Не используется
#define STK_UNKNOWN 0x12 // Не используется
#define STK_NODEVICE 0x13 // Не используется
#define STK_INSYNC 0x14 // ' '
#define STK_NOSYNC 0x15 // Не используется
#define ADC_CHANNEL_ERROR 0x16 // Не используется
#define ADC_MEASURE_OK 0x17 // Не используется
#define PWM_CHANNEL_ERROR 0x18 // Не используется
#define PWM_ADJUST_OK 0x19 // Не используется
#define CRC_EOP 0x20 // 'ПРОБЕЛ'
#define STK_GET_SYNC 0x30 // '0'
#define STK_GET_SIGN_ON 0x31 // '1'
#define STK_SET_PARAMETER 0x40 // '@'
#define STK_GET_PARAMETER 0x41 // 'А'
#define STK_SET_DEVICE 0x42 // 'B'
#define STK_SET_DEVICE_EXT 0x45 // 'Е'
#define STK_ENTER_PROGMODE 0x50 // 'P'
#define STK_LEAVE_PROGMODE 0x51 // 'Q'
#define STK_CHIP_ERASE 0x52 // 'R'
#define STK_CHECK_AUTOINC 0x53 // 'S'
#define STK_LOAD_ADDRESS 0x55 // 'U'
#define STK_UNIVERSAL 0x56 // 'V'
#define STK_PROG_FLASH 0x60 // '`'
#define STK_PROG_DATA 0x61 // 'а'
#define STK_PROG_FUSE 0x62 // 'б'
#define STK_PROG_LOCK 0x63 // 'c'
#define STK_PROG_PAGE 0x64 // 'd'
#define STK_PROG_FUSE_EXT 0x65 // 'е'
#define STK_READ_FLASH 0x70 // 'р'
#define STK_READ_DATA 0x71 // 'q'
#define STK_READ_FUSE 0x72 // 'r'
#define STK_READ_LOCK 0x73 // 'с'
#define STK_READ_PAGE 0x74 // 'т'
#define STK_READ_SIGN 0x75 // 'u'
#define STK_READ_OSCCAL 0x76 // 'v'
#define STK_READ_FUSE_EXT 0x77 // 'w'
#define STK_READ_OSCCAL_EXT 0x78 // 'x'
[AVR061: Протокол связи STK500](http://www.atmel.com/Images/doc2525.pdf), @Ignacio Vazquez-Abrams
Хороший момент! Я добавил несколько ссылок в ответ. Спасибо., @Nick Gammon
Обратите внимание, что описанный здесь процесс проверки использует чтение страницы, а это значит, что любой загрузчик, поддерживающий стандартное поведение проверки avrdude
, является загрузчиком, который поддерживает чтение содержимого флэш-памяти., @Chris Stratton
Эта обширная и описательная инструкция программы и анализ Optiboot/STK500 просто потрясающие. Спасибо, замечательный Ник Гэммон!, @David Refoua
- Не удается снова загрузиться после смены платы
- Ошибка при записи загрузчика
- Что означает avrdude: Device signature = 0x000000? Неисправная проводка? Проблема с программным обеспечением? Неправильная инструкция?
- Digispark Atinny85 не распознан (проблема с загрузчиком)
- Ошибка проверки Avrdude
- Atmega328p — переход на низкое энергопотребление 1,8 В с использованием генератора 4 МГц — прошивка загрузчика
- Переход к загрузчику из кода приложения в atmega328p
- Как загрузить Lilypad Arduino USB с помощью Arduino UNO
очень интересный пост! Просто еще вопрос. Какое программное обеспечение вы используете для отслеживания последовательной связи (изображения)?, @julio
Это результат работы логического анализатора, такого как Saleae Logic 8. https://www.saleae.com/ Очень симпатичный маленький анализатор. Раньше частота дискретизации 24 МГц стоила ~125, 150 долларов. Текущие скорости захвата составляют 100 и 500 МГц. >SPI, I2C и т. д. >Большинство цифровых коммуникаций используют определенный протокол, определяющий способ передачи информации. Программное обеспечение Logic имеет анализаторы протоколов, которые могут автоматически декодировать SPI, I2C, последовательный, 1-Wire, CAN, UNI/O, I2S/PCM, режим MP, Manchester, Modbus, DMX-512, параллельный, JTAG, LIN, Atmel SWI, MDIO, SWD, LCD HD44780, BiSS C, HDLC, HDMI CEC, PS/2, USB 1.1, Midi — или создайте свой собственный, @CrossRoads