Когда вы перезагружаете 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 немного нетерпелив, и время истекло, потому что он пытается снова с запросом «получить синхронизацию». На этот раз Optiboot отвечает немедленно.
Остальная часть загрузки описана на следующем рисунке. Пример производится загрузкой стоковой программы «Blink».
(Нажмите на изображение выше для увеличения)
Шаги:
- Запрос: получить синхронизацию? Ответ: Синхронизировано.
- Запрос: Получить параметр? (основная версия) Ответ: версия 4.
- Запрос: Получить параметр? (минорная версия) Ответ: версия 4.
Установите параметры устройства. Следующие параметры устройства отправляются на чип:
0x42 // STK_SET_DEVICE
0x86 // device code
0x00 // revision
0x00 // progtype: “0” – Both Parallel/High-voltage and Serial mode
0x01 // parmode: “1” – Full parallel interface
0x01 // polling: “1” – Polling may be used
0x01 // selftimed: “1” – Self timed
0x01 // lockbytes: Number of Lock bytes.
0x03 // fusebytes: Number of Fuse bytes
0xFF // flashpollval1
0xFF // flashpollval2
0xFF // eeprompollval1
0xFF // eeprompollval2
0x00 // pagesizehigh
0x80 // pagesizelow
0x04 // eepromsizehigh
0x00 // eepromsizelow
0x00 // flashsize4
0x00 // flashsize3
0x80 // flashsize2
0x00 // flashsize1
0x20 // Sync_CRC_EOP
Optiboot игнорирует все это и отвечает с помощью In Sync / OK. :)
Установить расширенные параметры устройства:
0x45 // STK_SET_DEVICE_EXT
0x05 // commandsize: how many bytes follow
0x04 // eeprompagesize: EEPROM page size in bytes.
0xD7 // signalpagel:
0xC2 // signalbs2:
0x00 // ResetDisable: Defines whether a part has RSTDSBL Fuse
0x20 // Sync_CRC_EOP
Optiboot также игнорирует все это и отвечает с помощью In Sync / OK.
Войдите в режим программирования. Ответ: Синхронизировано / ОК.
Читайте подпись. Optiboot отвечает, 0x1E 0x95 0x0F
фактически не читая подпись .
Напишите предохранители (четыре раза). Optiboot не записывает предохранитель, а просто отвечает In Sync / OK.
Адрес загрузки (изначально 0x0000). Адрес указывается словами (т. Е. Слово составляет два байта). Это устанавливает адрес, по которому будет записана следующая страница данных.
Страница программы (отправляется до 128 байт). Optiboot немедленно отвечает «In Sync». Затем происходит пауза около 4 мс, пока она фактически программирует страницу. Затем он отвечает «ОК».
Адрес загрузки (сейчас 0x0040). Это адрес 64 в десятичном виде, т.е. 128 байт от начала памяти программы.
Другая страница написана. Эта последовательность продолжается до тех пор, пока не будут написаны все страницы.
Адрес загрузки (обратно до 0x0000). Это для проверки записи.
Страница чтения (читается до 128 байт). Это для проверки. Обратите внимание, что даже если проверка не удалась, неверные данные уже были записаны в чип.
Выйти из режима программирования.
Что значит «не синхронизировано»?
Как видно из вышеизложенного, на каждом шаге последовательности программирования Arduino должен отвечать «In Sync» (0x14), возможно, после некоторых данных, а затем «OK» (0x10).
Если он «не синхронизирован», это означает, что avrdude не получил ответ «in sync». Возможные причины могут быть:
- Используется неверная скорость передачи
- В IDE выбран неверный последовательный порт
- В IDE выбран неверный тип платы
- Загрузчик не установлен
- Установлен неправильный загрузчик
- Плата не настроена на использование загрузчика (в предохранителях)
- Некоторые устройства подключены к контактам D0 и D1 на Arduino, что мешает последовательной связи
- Чип интерфейса USB (ATmega16U2) не работает должным образом
- Неправильные часы для доски
- Неправильные настройки предохранителей на Atmega328P (например, «делим часы на 8»)
- Повреждена плата / чип
- Неисправный USB-кабель (некоторые USB-кабели обеспечивают только питание и не предназначены для передачи данных, например, дешевые кабели для вентиляторов USB)
Что такое "синхронно"?
Как упоминалось выше, ответ «In sync» означает, что Arduino (загрузчик) синхронизирован с загружаемой программой.
Какой протокол используется?
Протокол является протоколом STK500, задокументированным Atmel. Смотрите ссылки ниже.
Ссылки
Примечание : STK500 версии 2 не используется в Optiboot, но он включен для информации, если вы используете платы, такие как Mega2560.
Константы STK500
/* STK500 constants list, from AVRDUDE */
#define STK_OK 0x10
#define STK_FAILED 0x11 // Not used
#define STK_UNKNOWN 0x12 // Not used
#define STK_NODEVICE 0x13 // Not used
#define STK_INSYNC 0x14 // ' '
#define STK_NOSYNC 0x15 // Not used
#define ADC_CHANNEL_ERROR 0x16 // Not used
#define ADC_MEASURE_OK 0x17 // Not used
#define PWM_CHANNEL_ERROR 0x18 // Not used
#define PWM_ADJUST_OK 0x19 // Not used
#define CRC_EOP 0x20 // 'SPACE'
#define STK_GET_SYNC 0x30 // '0'
#define STK_GET_SIGN_ON 0x31 // '1'
#define STK_SET_PARAMETER 0x40 // '@'
#define STK_GET_PARAMETER 0x41 // 'A'
#define STK_SET_DEVICE 0x42 // 'B'
#define STK_SET_DEVICE_EXT 0x45 // 'E'
#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 // 'a'
#define STK_PROG_FUSE 0x62 // 'b'
#define STK_PROG_LOCK 0x63 // 'c'
#define STK_PROG_PAGE 0x64 // 'd'
#define STK_PROG_FUSE_EXT 0x65 // 'e'
#define STK_READ_FLASH 0x70 // 'p'
#define STK_READ_DATA 0x71 // 'q'
#define STK_READ_FUSE 0x72 // 'r'
#define STK_READ_LOCK 0x73 // 's'
#define STK_READ_PAGE 0x74 // 't'
#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'