Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 1 mar 2025, o 08:16


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 10 ] 
Autor Wiadomość
PostNapisane: 10 sty 2015, o 13:06 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 cze 2013
Posty: 137
Lokalizacja: Kraków
Pomógł: 0

Cześć wszystkim!
Na wstępie zaznaczę, że nie miałem jeszcze do czynienia z tematem bootloaderów, więc nie wszystko jest dla mnie całkowicie jasne :). Rozglądam się za jakimś prostym bl który umożliwi mi wgrywanie wsadu przez uart, ale w trybie half-duplex, czyli z jednego pinu GPIO działającego na zmianę jako RX i TX. Poszperałem w sieci i znalazłem kilka które by mi odpowiadały, ale z ciekawości chciałbym trochę liznąć temat bootloaderów i pobawić się w sekcji BLS procka.
Tu pojawia się moje pytanie - jak się za to zabrać w Eclipse? Wyczytałem, że w Atmel Studio wystarczy we właściwościach projektu zmienić początkowy adres programu na odpowiednio daleki (w zależności od procka i wybranej wielkości BLS), jednak nie mogę znaleźć niczego takiego w ustawieniach Eclipse.
Wybaczcie jeśli pytanie jest głupie, ale przyznam że nigdy nie intrygowało mnie samo środowisko programistyczne - zainstalowałem według filmu Mirka i tyle :).

_________________
Więcej dziwactw na: www.youtube.com/user/mopsiok



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 sty 2015, o 15:00 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 maja 2014
Posty: 1089
Pomógł: 34

a BLSy w MkBootLoaderze ogladales jako cos na czym mogl bys zawiesic oko :D ?

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 sty 2015, o 21:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 cze 2013
Posty: 137
Lokalizacja: Kraków
Pomógł: 0

Dzięki za te linki, szczególnie ten pierwszy to prawdziwa skarbnica wiedzy ;).
Miałem kilka problemów ale ostatecznie jestem po pierwszym udanym teście pracy na NRWW. Co prawda zamiast bootloadera siedzi tam póki co migająca dioda :mrgreen:, ale pierwsze lody przełamane!

Gdyby ktoś jeszcze miał podobny problem, podsumuję co musiałem zrobić żeby całość ruszyła:
- napisać NRWW-owy hello world w postaci migającej diody :D http://pastebin.com/UxVBaKWV
- w lokalizacji którą wyżej podał kolega mokrowski wklepać poniższy tekst. Wartość 0x3800 to adres początku sekcji bootloadera i zależy on od jego wielkości, którą ustawia się fusebitami BOOTSZ1..0 (0x3800 odpowiada wartości domyślnej fusebitów w atmega168, czyli bootloader na 1024 słowa). W datasheecie można znaleźć adresy początkowe dla różnych wielkości, ale należy je pomnożyć przez 2, bo są to adresy podane w słowach, a argument ma być wyrażony w bajtach.
Kod:
-Wl,--section-start=.text=0x3800
- skompilować kod i skopiować hexa do jakiegoś folderu, zmieniając mu nazwę na boot.hex
- użyć dowolnego innego programu (może być drugi hello world tylko że na innej diodzie ^^) i skopiować jego hexa do tego samego folderu, zmieniając nazwę na app.hex
- wejść wierszem poleceń do folderu i wydać poniższe polecenie (srec_cat jest instalowany domyślnie z winAVR). Przy wgrywaniu hexa czyszczona jest cała pamięć, więc chcąc wgrać jednocześnie soft domyślny i "bootloaderowy", trzeba je połączyć do jednego pliku.
Kod:
srec_cat app.hex -I boot.hex -I -o combined.hex -I
- wgrać plik combined.hex - od tego momentu wykonywać się będzie boot.hex gdy zaprogramujemy fusebit BOOTRST, albo app.hex gdy bit pozostanie niezaprogramowany

@RafPe Przyznam że obczaiłem ten program dopiero dzisiaj, nie wiedziałem że Mirek udostępnił w nim kod i makefile bootloadera. No patrzę na ten kod i trochę mnie on przeraża :D. Nie wiem co to się wyczynia z tymi wszystkimi __init, ale czuję że muszę się dokształcić zanim zacznę pisać coś po swojemu...

_________________
Więcej dziwactw na: www.youtube.com/user/mopsiok



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 sty 2015, o 23:15 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 maja 2014
Posty: 1089
Pomógł: 34

Fajnie , ze cos znalazles ! Ja jestem na etapie uzywania :) pisac moze bede za kilka lat ale fajnie ze znalazles te info i sie nimi juz podzieliles! Daj znac jak Ci pojdzie dalej!

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 sty 2015, o 10:14 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 cze 2013
Posty: 137
Lokalizacja: Kraków
Pomógł: 0

Ok dzięki za materiały, trochę mi to wyjaśniło sprawę, ale wciąż nie do końca rozumiem jakie jest praktyczne zastosowanie tych wszystkich initów ;). Znaczy... co za różnica czy dany fragment kodu wykona się teraz czy kilka taktów później, skoro i tak wszystkie polecenia lecą w zadanej kolejności? :)
W kodzie bootloadera Mirka widzę że w init2 wykonuje się kod do "inicjalizacja wskaźnika stosu, rejestru z zerem i rejestru flag" - czy takie rzeczy nie powinny się wykonać "same" po każdym resecie procka? Mam na myśli to, że zazwyczaj czegoś takiego się nie zamieszcza w programie a stos i tak działa :D.

_________________
Więcej dziwactw na: www.youtube.com/user/mopsiok



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 sty 2015, o 12:18 

Pomógł: 0

mopsiok napisał(a):
zazwyczaj czegoś takiego się nie zamieszcza w programie a stos i tak działa
Umieszcza umieszcza - tylko z automatu robi to toolchain. Po włączeniu zasilania procek (dotyczy AVR) zaczyna wykonywać kod od określonego adresu pamięci: od zera lub "od bootloadera" w zależności od konfiguracji fuse'a BOOTRST (na podstawie pdf'a do megi8). Cała reszta zależy już od programu.

Poeksperymentuj z podglądaniem pliku *.lss - asembler nie kłamie ;d Np. po skompilowaniu takiego wspaniałego dzieła programistycznego:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


czyli programu, który generalnie nic nie robi, powstał taki (po)twór:

Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W telegraficznym skrócie, lecąc od góry:
- pod adresem 0 jest instrukcja skoku (jmp) do etykiety wskazującej koniec tablicy wektorów przerwań (__ctors_end) - tym sposobem po resecie procesor wykona tą instrukcję i "przeskoczy" za tablicę wektorów - inaczej wykonałby po kolei wszystkie procedury obsługi przerwań
- dalej są instrukcje skoków do procedur obsługi kolejnych przerwań - ponieważ w programie nie ma tych procedur, wszystkie skierowane są do "__bad_interrupt" - to taka "awaryjna" funkcja obsługi przerwania
- za tablicą przerwań jest fragment kodu odpowiedzialny za wyzerowanie rej. r1, SREG i ustawienie adresu końca stosu
- kolejny kawałek (od etykiety __do_copy_data) powoduje przypisanie zmiennym ich wartości początkowych - w moim programie chodzi o skopiowanie stringu "Ala ma kota..." z pamięci flash do pamięci SRAM pod adres gdzie siedzi zmienna tab1
- następny kawałek to zerowanie pozostałych zmiennych globalnych i statycznych (tab2)
- wreszcie w 58 linii jest skok do funkcji main :)

Samo nic się nie wykonuje ;) Całą brudną robotę odwala toolchain.



Góra
  
cytowanie selektywne  Cytuj  
PostNapisane: 11 sty 2015, o 13:29 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 cze 2013
Posty: 137
Lokalizacja: Kraków
Pomógł: 0

Łał, dzięki za tak dokładną rozpiskę :D. Tylko właśnie nurtuje mnie to, że skoro toolchain i tak wykonuje te operacje, to po co w bootloaderze Mirka są one wykonywane ręcznie? Widzę że kod jest ogólnodostępny, więc chyba nie będzie problemu jak przytoczę tu jego część:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Jeśli dobrze zrozumiałem, to ręczna obsługa __vectors jest konieczna, bo Mirek wsadził coś za kodem z wektorami i adresy się nie zgadzają, i musi ręcznie przejść tam gdzie chce :D. Dobrze rozumuję?
Jak już wykona się skok do __init2, to tu z kolei jest ręczna inicjalizacja stosu i kasowanie rejestru zero. I tu z kolei nie wiem czemu - z tego co wyczytałem to w .init2 te operacje są robione automatycznie...
__init3 jest wg Twoich materiałów nieużywany przez toolchain, więc tutaj dopisana została dodatkowa funkcjonalność, tylko też nie za bardzo rozumiem co to i czemu to tu musi być :). Co z tym watchdogiem jest, że nawet jak jest domyślnie wyłączony to trzeba go wyłączać ręcznie? ^^
No i ostatnia niejasna dla mnie sprawa, czyli skok do main w __init9 - według opisu w .init9 jest automatyczny skok, więc czemu tutaj zostało to zapisane ręcznie?

Przepraszam że tak męczę, ale jest to dość ciekawe zagadnienie i niestety nie do końca dla mnie jasne czemu akurat to a nie co innego zostało "powtórzone"... :)

_________________
Więcej dziwactw na: www.youtube.com/user/mopsiok



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 sty 2015, o 18:58 

Pomógł: 0

Nie wiem, ale mogę strzelać ;d Ręczna obsługa tablicy wektorów na pewno pozwoli zaoszczędzić trochę miejsca - a im mniejszy bootloader tym lepiej - można więc uszczknąć kilka B wywalając zbędne elementy z tablicy wektorów. Można też zrezygnować np. z zerowania zmiennych - kolejne kilka B do przodu.

W komentarzu jest informacja o opcji "nostartfiles" - jej użycie powoduje, że toolchain nie odwala całej "brudnej roboty" (inicjalizacji zmiennych, ustawienia stosu, tablicy przerwań...) :) Rozmieszczenie sekcji w pamięci jest zdefiniowane w skrypcie linkera - z komentarza w kodzie wynika że za sekcją .vectors (umieszczoną na początku pamięci flash) umieszczone są "stałe" - nie można więc pozwolić żeby procek próbował wykonać je jako kod. Dlatego w sekcji .vectors - która umieszczana jest pod adresem 0 - wrzucony jest rozkaz skoku (jmp) "za" te dane.

W całym tym podziale na sekcje initx nie ma żadnej ukrytej magii, nic się nie dzieje automatycznie, sprzętowo itd.. (chyba, że się mylę) ;) Ktoś sobie przyjął podział kodu rozruchowego na kilka sekcji, określił co powinno w każdej z nich być. Położenie sekcji w pamięci (przede wszystkim ich kolejność) określona jest w skrypcie linkera - umieszczając kod w danej sekcji wiesz "kiedy" on się wykona - w szczególności przydatna może być informacja o tym czy już jest ustawiony stos i czy są skopiowane wartości zmiennych. Np jeśli korzystasz z zewnętrznej pamięci RAM to musisz skonfigurować interfejs komunikujący się z tą pamięcią zanim skrypt rozruchowy zacznie kopiowanie wartości zmiennych z pamięci flash do ram. Umieszczasz więc konfigurację tego interfejsu w odpowiedniej sekcji rozruchowej, która wykonuje się przed inicjalizacją zmiennych.

Ad watchdog - niektóre procki (do doczytania w manualu) mają tak, że jeśli zresetują się wskutek zadziałania hotdoga to po resecie pozostaje on włączony. Stąd profilaktyczne wyłącznie.


Autor postu otrzymał pochwałę


Góra
  
cytowanie selektywne  Cytuj  
PostNapisane: 11 sty 2015, o 20:09 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 cze 2013
Posty: 137
Lokalizacja: Kraków
Pomógł: 0

Czyli jeśli dobrze pojąłem, to cały ten "powtórzony" kod wynika z tego, że w opcjach kompilacji było włączone nostartfiles żeby zaoszczędzić miejsce (np. wywalenie skoków do przerwań których i tak nie ma), i przez to wszystko co automatycznie robił toolchain trzeba było napisać samemu? Dzięki serdeczne, chyba już wszystko zrozumiałem :). Za watchdoga też dzięki, nie wiedziałem że gadzina może pozostać włączona po resecie ;).

Cóż, skoro rozwiałem już nurtujące mnie wątpliwości, chyba zacznę coś samemu kodzić :D. Jakby były jakieś problemy to będę jeszcze pisać.

Dzięki raz jeszcze Panowie, dużo mi wyjaśniliście!

_________________
Więcej dziwactw na: www.youtube.com/user/mopsiok



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 sty 2015, o 21:37 

Pomógł: 0

Co do "nostartfiles" to byłem święcie przekonany, że ta opcja powoduje wyrzucenie wszystkich "standardowych" kodów rozruchowych - tak, że zostaje tylko kod z "main" wrzucony pod adres 0 we flashu. Dokumentacja gcc niby to potwierdza:
Cytuj:
Do not use the standard system startup files when linking.
źródło
Skompilowałem program (ten z pustą pętlą w main) z opcją "nostartfiles" i o dziwo zniknęła tylko tablica wektorów... inicjalizacja danych została, tego się nie spodziewałem :roll: Także musisz poczekać na wypowiedź kogoś mądrzejszego - jakto z tym "nostartfiles" jest dokładnie :)



Góra
  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 10 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 3 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO