Что происходит, когда код загружается с помощью загрузчика?

Что на самом деле происходит, когда я загружаю новый скетч в Arduino Uno с помощью загрузчика Optiboot?

  • Что отправляется на Arduino?
  • Как он реагирует?
  • Что означает «не синхронизировано»?
  • Что вообще такое «синхронизировать»?

Примечание. Это «справочный вопрос».

, 👍15

Обсуждение

очень интересный пост! Просто еще вопрос. Какое программное обеспечение вы используете для отслеживания последовательной связи (изображения)?, @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


1 ответ


Лучший ответ:

22

При сбросе настроек Uno с запущенным загрузчиком Optiboot загрузчик сначала трижды мигает на контакте 13.

Прошивка контакта 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".

Процесс загрузки Optiboot

(Нажмите на изображение выше, чтобы увеличить его)


Шаги следующие:

  • Запрос: Получить синхронизацию? Ответ: Синхронизировано.
  • Запрос: Получить параметр? (основная версия) Ответ: версия 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. См. ссылки ниже.


Ссылки

Примечание: 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