Czy ktoś może wyjaśnić, jak działa bootloader Arduino ? Nie szukam tutaj odpowiedzi na wysokim poziomie, przeczytałem kod i mam sedno. Przeczytałem również ten drugi post (byłem nawet jednym z jego odpowiedzi).
Pomiędzy Arduino IDE i kodem bootloadera zachodzi szereg interakcji protokołów, co ostatecznie prowadzi do szeregu wbudowanych instrukcji asemblacyjnych, które samoczynnie programują flash z programem przesyłanym przez interfejs szeregowy.
To, czego nie jestem pewien, dotyczy linii 270:
void (*app_start)(void) = 0x0000;
... który rozpoznaję jako deklarację i inicjalizację na NULL wskaźnika funkcji. Nastąpiły kolejne wywołania app_start w miejscach, w których bootloader ma delegować wykonywanie kodu załadowanego przez użytkownika.
Z pewnością app_start
w pewnym momencie musi uzyskać wartość inną niż NULL, aby to wszystko się połączyło. Nie widzę tego w kodzie bootloadera ... czy jest on magicznie powiązany z programem ładowanym przez bootloader? Zakładam, że głównym modułem rozruchowym jest punkt wejścia do oprogramowania po resecie układu.
Około 70 linii wiersza musi zawierać ukryty pierścień dekodera, który informuje główny program, gdzie naprawdę jest app_start? A może to jakaś ukryta wiedza wykorzystywana przez Arduino IDE? Wiem tylko, że jeśli ktoś nie zmieni app_start tak, aby wskazywał na miejsce inne niż 0, kod bootloadera po prostu zakręci się na zawsze ... więc jaka jest sztuczka?
Czy w osobnej notatce byłoby możliwe, aby kod programu ładującego opierał się na przerwaniach, czy jest to nie-nie?
Edytować
Jestem zainteresowany próbą przeniesienia bootloadera do Tiny AVR (szczególnie ATTiny44A), który nie ma oddzielnej przestrzeni pamięci dla kodu bootloadera. Ponieważ staje się dla mnie oczywiste, że kod programu ładującego zależy od pewnych ustawień bezpieczników i obsługi mikroukładów, myślę, że tak naprawdę jestem zainteresowany, aby dowiedzieć się, co trzeba zrobić, aby przenieść program ładujący do układu, który nie ma tych bezpieczników i sprzętu wsparcie (ale nadal ma zdolność do samodzielnego programowania)?
Myślałem, że mogę użyć implementacji AVR307, aby użyć USI jako półdupleksowego UART (używa przerwania Timer0 i przerwania zmiany pinów). Czy ktoś może zaoferować wskazówki dotyczące pisania / przenoszenia kodu programu ładującego dla układu, który nie obsługuje sprzętowego programu ładującego?
Zakładam, że umieściłbym mój kod bootloadera w normalnej lokalizacji dla adresu main (np. 0x029e lub gdziekolwiek kompilator ustawia main). Zrobiłbym to, aby „adres” w kodzie bootloadera dodał przesunięcie, które umieściło mnie tuż za końcem main i ustawiłem „app_start” na ten adres. Czy dobrze o tym myślę, czy coś kompletnie mi brakuje? Dzięki!
EDYCJA 2
FWIW, znalazłem udokumentowany proces ładowania szkiców Arduino na ATTiny85 , do którego pierwotnie dążyłem z tym pytaniem ... całkiem nieźle
źródło
Odpowiedzi:
To nie jest wskaźnik NULL. To naprawdę jest adres początku kodu aplikacji, do którego przeskakuje bootloader. Linker organizuje uruchomienie kodu aplikacji pod adresem 0. Patrz tabela 26-6 w arkuszu danych ATMEGA168.
Kod bootloadera zaczyna się wyżej we flashu. Dokładnie gdzie zależy od bezpieczników bootloadera.
źródło