Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Atmega32][C] - Bootloader USB

Wojtek001 25 Maj 2013 11:18 1779 12
  • #1 25 Maj 2013 11:18
    Wojtek001
    Poziom 15  

    Potrzebuje wgrać bootloader USB do Atmegi32. Znalazłem taki bootloader który prawie spełnia moje oczekiwania:
    http://www.obdev.at/products/vusb/usbasploader.html
    Powyższy bootloader symuluje USBasp. Autor podaje że aby uruchomić bootloader należy zewrzeć zworkę podając GND na jedno z wejść mikrokontrolera. Ja jednak nie chce aby bootloader uruchamiał się na początku i nie chce żadnej zworki.

    Postanowiłem więc to zmienić.
    1) Zajrzałem do pliku nagłówkowego bootloadera. Jest tam taka definicja preprocesora:

    Code:
    #define bootLoaderCondition()  ((PIND & (1 << JUMPER_BIT)) == 0)
    
    JUMPER_BIT to akurat 7 (ale to nieistotne). Jak widzimy mamy tam maske i sprawdzanie stanu bitu przez porównanie do 0.


    Ja to zamieniam w ten sposób:
    Code:
    #define bootLoaderCondition()  (1)


    Teraz bootloader nie będzie sprawdzał żadnej zworki tylko od razu się włączy.

    2) Bootloader był tak napisany żeby korzystać z domyślnie ustawionego fusebita odpowiedzialnego za "reset wektor" (Boot Reset). Wówczas kiedy mikrokontroler się uruchomi od razu po resecie uruchomi się sekcja pamięci w której jest bootloader.
    Ja przeprogramowuje fusebit Boot Reset na 0 dzięki czemu sam chce decydować kiedy wywołam bootloader. Będzie to wywoływane na skutek jakiegoś zdarzenia - np wejścia do jakiejś pozycji w menu.
    I teraz pytanie: Jak skoczyć do "Boot Flash Section" w środku programu? W atmedze32 ta sekcja zaczyna się od adresu $3FFF. Tzn cała sekcja "No-Read-While-Write" mieści się w przedziale od $3800 do $3FFF ale wolne miejsce może być zapełniane też przez pamięć aplikacji więc chyba bootloader jest czytany od "końca" jak stos w RAM?

    0 12
  • #2 25 Maj 2013 12:20
    tmf
    Moderator Mikrokontrolery Projektowanie

    Nie, sekcja bootloadera jest zapełniana tak jak normalny Flash. Ty musisz skoczyć na początek sekcji określony przez stan odpowiednich fusebitów. Skoczyć możesz wykonując instrukcję asemblera, w c:
    asm volatile ("jmp 0xcostam");
    lub definiując wskaźnik na funkcję.
    Swoją drogą nie prościej użyć procka, który ma USB-device? Wyjdzie nawet taniej niż taka ATMega32.

    0
  • #3 25 Maj 2013 12:41
    Wojtek001
    Poziom 15  

    Przed chwilą sprawdziłem na tme : Atmega32A w smd kosztuje 9,36zł dużo mnie niż inne mikro kontrolery AVR o takiej ilości pinów i pamięci.
    Powyższy Bootloader zajmuje 2kb w związku z tym:
    dobra w datsheecie wysczytałem że dla 2kb sekcja bootloadera zaczyna się na 0x3800
    mam wpisać coś takiego:

    Code:
    asm volatile ("jmp 0x3800"); 

    0
  • Pomocny post
    #4 25 Maj 2013 12:57
    tmf
    Moderator Mikrokontrolery Projektowanie

    Taka ATXMEGA128A3U kosztuje w seguro niecałe 14 zł, a ma 4 razy więcej pamięci i więcej pinów, więcej wszystkiego :)
    Co do adresu - jak pisałem, adres określony jest stanem odpowiednich fusebitów, a nie długością bootloadera. Czyli skaczesz na początek bloku bootloadera.

    Dodano po 1 [minuty]:

    Wojtek001 napisał:

    1) Bit SPIEN ma zostać domyślnie ustawiony? Wiem że jak go zmienię to wyjmę sobie dywanik z pod nóg ale chyba nie muszę nic z nim robić?
    2)


    Bitu SPIEN w trybie SPI i tak nie jesteś w stanie zmienić, do tego potrzebny jest JTAG. Nie zawracaj sobie nim głowy.

    0
  • #5 25 Maj 2013 12:58
    Wojtek001
    Poziom 15  

    Dzięki wielkie bo to była moja główna wątpliwość. Teraz mam kilka pytań dodatkowych:

    2) BOOTSZ1 i BOOTSZ0 mają zostać ustawione na 0
    3) BOOTRST ma być wyzerowany, domyślnie jest 1.
    Coś jeszcze trzeba zrobić?

    0
  • #6 25 Maj 2013 13:02
    tmf
    Moderator Mikrokontrolery Projektowanie

    Ustawienie bitów BOOTSZ zależy od tego, gdzie załadujesz bootloader. Jeśli masz wersję skompilowaną to musisz wiedzieć pod jaki adres została skompilowana i tak ustawić te fusebity. Jeśli kompilujesz to adres musisz ustawić jako adres sekcji przy kompilacji bootloadera i pod ten adres ustawić BOOTSZ.
    BOOTRST możesz wyzerować. Z drugiej strony jednak lepszym pomysłem jest start z bootloadera i potem odpalenie aplikacji. Dlaczego? Bo jak skaszani się update aplikacji to nie będziesz miał szans wejścia w bootloader.

    0
  • #7 25 Maj 2013 13:13
    Wojtek001
    Poziom 15  

    BOOTSZ to chyba odpowiadają za wielkość bootloadera a nie adres?

    W każdym razie dobrze że zwróciłeś uwagę na adres bo bootloader domyślnie jest stworzony dla atmegi8 więc ona ma pewnie inny adres poczatkowy sekcji NRWW i trzeba to zmienić.

    0
  • #8 25 Maj 2013 13:23
    tmf
    Moderator Mikrokontrolery Projektowanie

    BOOTSZ określają początek sekcji bootloadera, a przez to pośrednio jego wielkość - bootloader rozciąga się od początku jego sekcji do końca dostępnej pamięci Flash.

    0
  • #9 25 Maj 2013 13:29
    Wojtek001
    Poziom 15  

    W ATmedze8 przy 2kb bootloadera sekcja zaczyna się od 0xC00 a więc inaczej niż w Atmedze32. Rozumiem że adres 0xC00 znajduje się gdzieś w plikach bootloadera i mam go podmienić ma 0x3800 , gdzie mam go mniej więcej szukać?

    0
  • #10 25 Maj 2013 13:45
    tmf
    Moderator Mikrokontrolery Projektowanie

    To zależy od projektu i w jakim jest IDE. Adres może być ustawiony w AVR/Atmel Studio, w pliku makefile, gdziekolwiek. Chodzi o przesunięcie sekcji .text.

    0
  • #11 25 Maj 2013 13:54
    Wojtek001
    Poziom 15  

    w makefile znalazłem coś takiego (widać jednak że był robiony pod AT168):

    Code:
    F_CPU = 16000000
    
    DEVICE = atmega168
    # BOOTLOADER_ADDRESS is 1800 for 8k devices, 3800 for 16k and 7800 for 32k.
    BOOTLOADER_ADDRESS = 3800
    FUSEOPT = $(FUSEOPT_168)
    LOCKOPT = -U lock:w:0x2f:m


    po hash są komentarze? bo w wyżej zamieszczonym fragmencie piszą że przy 32kb trzeba zamienić na 7800 adres, teraz sobie to przeliczyłem i rzeczywiście, musiałem źle spojrzeć do noty.
    W każdym razie trzeba zamienić tamto na to:
    Code:
    F_CPU = 16000000
    
    DEVICE = atmega32
    # BOOTLOADER_ADDRESS is 1800 for 8k devices, 3800 for 16k and 7800 for 32k.
    BOOTLOADER_ADDRESS = 7800
    FUSEOPT = $(FUSEOPT_168)
    LOCKOPT = -U lock:w:0x2f:m

    niepokoi mnie co to jest to FUSE_OPT

    tzn dalej jest coś takiego:
    Code:
    FUSEOPT_8 = -U hfuse:w:0xc0:m -U lfuse:w:0x9f:m
    
    FUSEOPT_88 = -U hfuse:w:0xd6:m -U lfuse:w:0xdf:m -U efuse:w:0x00:m
    FUSEOPT_168 = -U hfuse:w:0xd6:m -U lfuse:w:0xdf:m -U efuse:w:0x00:m
    FUSEOPT_328 = -U lfuse:w:0xf7:m -U hfuse:w:0xda:m -U efuse:w:0x03:m
    więc chyba to są ustawienia fusów ale ja sobie to mogę ręcznie zrobić?Z tymi fusami to już sobie poradzę, przeliczę i w makefilu pozmieniam.

    Czy mogą mnie jeszcze spotkać jakieś niespodzianki w związku z użyciem innego AVR niż był przewidziany?

    0
  • #12 25 Maj 2013 14:19
    tmf
    Moderator Mikrokontrolery Projektowanie

    Tak, to jest ustawienie fusów. Niekoniecznie możesz je zmienić ręcznie, bo jeśli cały makefgile wywołuje avrdude i mu np. przekaże te fusebity to już tak będą one ustawione. Jeśli błednie to konsekwencją może być zablokowanie MCU.
    Co do innych niespodzianek - tak, inne nazwenictwo portów, czy jakiś układów, które wykorzystuje ten bootloader. Trzeba przejrzeć kod.

    0
  • #13 25 Maj 2013 14:34
    Wojtek001
    Poziom 15  

    Szukam miejsc w plikach bootloadera które odwołują się do procesora który wybranow w makefile i znalażłem w main.c coś takiego:

    Code:
    static const uchar  signatureBytes[4] = {
    
    #ifdef SIGNATURE_BYTES
        SIGNATURE_BYTES
    #elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__)
        0x1e, 0x93, 0x07, 0
    #elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48P__)
        0x1e, 0x92, 0x05, 0
    #elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88P__)
        0x1e, 0x93, 0x0a, 0
    #elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__)
        0x1e, 0x94, 0x06, 0
    #elif defined (__AVR_ATmega328P__)
        0x1e, 0x95, 0x0f, 0
    #else
    #   error "Device signature is not known, please edit main.c!"
    #endif
    };

    Skąd wziąść informacje na temat signature bytes dla AT32 ? Szukam i tego nigdzie nie mogę znaleźć. ogólnie czytałem że nie ma większych problemów z uruchamianiem tego bootloadera na innych AVR a powyższy fragment kodu jest to jedyny fragment odwołujący się do rodzaju kontrolera.

    Dobra znalazłem ala AT32 : 0x1E ,0x95, 0x02

    0