Po zresetowaniu Uno z uruchomionym modułem ładującym Optiboot, moduł ładujący najpierw trzykrotnie mruga pin 13.
Górna linia (szara) jest wysyłana do Arduino, środkowa linia (pomarańczowa) jest wysyłana z Arduino.
Podczas gdy tak się dzieje, program avrdude
działający na twoim komputerze wysyła zapytanie do urządzenia:
STK_GET_SYNC / CRC_EOP (0x30/0x20)
Arduino nie zauważa pierwszego „zsynchronizuj”, ponieważ jest zajęty flashowaniem pinu 13. Po zakończeniu zauważa „zsynchronizuj” (będzie buforowany przez sprzęt szeregowy) i odpowiada:
STK_INSYNC / STK_OK (0x14/0x10)
Wygląda na to, że avrdude jest trochę niecierpliwy i przekroczył limit czasu, ponieważ próbuje ponownie z zapytaniem „get sync”. Tym razem Optiboot odpowiada natychmiast.
Reszta przesyłania jest opisana na następnym obrazie. Przykład wyprodukowano przesyłając program akcji „Blink”.
(Kliknij na obrazek powyżej, aby uzyskać większą wersję)
Kroki są następujące:
- Zapytanie: Get Sync? Odpowiedz: w synchronizacji.
- Zapytanie: uzyskać parametr? (wersja główna) Odpowiedź: wersja 4.
- Zapytanie: uzyskać parametr? (wersja pomniejsza) Odpowiedź: wersja 4.
Ustaw parametry urządzenia. Do układu wysyłane są następujące parametry urządzenia:
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 ignoruje to wszystko i odpowiada przy pomocy In Sync / OK. :)
Ustaw rozszerzone parametry urządzenia:
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 również je ignoruje i odpowiada przy pomocy In Sync / OK.
Wejdź w tryb programu. Odpowiedz: w synchronizacji / OK.
Przeczytaj podpis. Optiboot odpowiada 0x1E 0x95 0x0F
bez faktycznego czytania podpisu .
Napisz bezpieczniki (cztery razy). Optiboot nie zapisuje bezpiecznika, a jedynie odpowiada w synchronizacji / OK.
Załaduj adres (początkowo 0x0000). Adres jest słowny (tzn. Słowo ma dwa bajty). Ustawia adres, pod którym będzie zapisywana następna strona danych.
Strona programu (wysyłanych jest do 128 bajtów). Optiboot natychmiast odpowiada „w synchronizacji”. Następnie następuje przerwa około 4 ms, podczas której programuje stronę. Następnie odpowiada „OK”.
Załaduj adres (teraz 0x0040). Jest to adres 64 w systemie dziesiętnym, tj. 128 bajtów od początku pamięci programu.
Napisano kolejną stronę. Ta sekwencja trwa, dopóki wszystkie strony nie zostaną zapisane.
Załaduj adres (z powrotem do 0x0000). Służy to do weryfikacji zapisu.
Strona odczytu (odczytywanych jest do 128 bajtów). To jest do weryfikacji. Pamiętaj, że nawet jeśli weryfikacja się nie powiedzie, złe dane zostały już zapisane w układzie scalonym.
Wyjdź z trybu programowania.
Co oznacza „niezsynchronizowane”?
Jak widać z powyższego, na każdym etapie sekwencji programowania Arduino ma odpowiedzieć „In Sync” (0x14), ewentualnie po nim niektóre dane, a następnie „OK” (0x10).
Jeśli nie jest zsynchronizowany, oznacza to, że avrdude nie otrzymał odpowiedzi „zsynchronizowany”. Możliwe przyczyny to:
- Użyto niewłaściwej prędkości transmisji
- Wybrano niewłaściwy port szeregowy w IDE
- Wybrano niewłaściwy typ płytki w IDE
- Brak zainstalowanego programu ładującego
- Zainstalowano nieprawidłowy program ładujący
- Płytka nie skonfigurowana do używania programu ładującego (w bezpiecznikach)
- Niektóre urządzenia podłączone do pinów D0 i D1 na Arduino, zakłócają szeregowe komendy
- Układ interfejsu USB (ATmega16U2) nie działa poprawnie
- Zły zegar na tablicy
- Niewłaściwe ustawienia bezpiecznika w Atmega328P (np. „Podziel zegar przez 8”)
- Płyta / chip uszkodzony
- Wadliwy kabel USB (niektóre kable USB zapewniają jedynie zasilanie i nie są przeznaczone do transmisji danych, np. Tanie kable dla fanów USB)
Co to jest „zsynchronizowany”?
Jak wspomniano powyżej, odpowiedź „W synchronizacji” oznacza, że Arduino (bootloader) jest zsynchronizowany z programem ładującym.
Jaki protokół jest używany?
Protokół jest protokołem STK500 udokumentowanym przez Atmel. Zobacz odnośniki poniżej.
Bibliografia
Uwaga : STK500 wersja 2 nie jest używany w Optiboot, ale jest dołączony do informacji w przypadku korzystania z płyt takich jak Mega2560.
Stałe 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'