logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Pobieranie plików z serwera przez SIM868 do Optiboot na Atmega328PB

Karol966 29 Cze 2022 21:59 1257 20
  • #1 20081282
    Karol966
    Poziom 31  
    Cześć,

    Pracuję nad bootloaderem, który umożliwi zaprogramowanie procesora plikiem z serwera.
    Plik pobieram i tnę na kawałki (dowolnej wielkości, aktualnie 128 bajtów) z pomocą modułu SIM868 (póki co w osobnym projekcie).
    Uruchomiłem projekt bootloadera optiboot w Microchip Studio 7. Były jakieś dziwne problemy, ale udało się wgrać program bootloadera do procesora. Musiałem każdą solucję ręcznie przeładowywać aby można było skompilować projekt, ponadto był błąd (a w zasadzie 3 takie same dla różnych procesorów dotyczące baudcheck więc zakomentowałem te linie w pliku make:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Zmieniłem pin diody, która po zaprogramowaniu procesora szczęśliwie mruga w koło (3 mrugnięcia, chwila pauzy i tak w nieskończoność).

    Ustawiłem fusebity (aktualnie BOOTSZ zgodnie z rozmiarem, po integracji obu w/w programów zmienię na 2024 słowa, gdyż sama obsługa pobierania plików przez HTTP GET zajmuje mi 3kB i nie mam pomysłu na zmniejszenie jej rozmiaru - nie potrafię):
    Pobieranie plików z serwera przez SIM868 do Optiboot na Atmega328PB

    Mam pytanie, czy przypadkiem dioda nie powinna inaczej się zachowywać? Tzn mrugnąć zadaną ilość razy (wg opisu na stronie 3, choć zmieniałem tą ilość w programie to nadal miga 3 razy) a potem czekać na rozkazy/ dane na porcie?
    Czym mogę wysłać testowo flash do optiboot'a? Pewnie przez samo środowisko Arduino a to raczej odpada, może przez opcje "Send File" w br@y++ terminal (tylko, że się program wysypuje). Docelowo to serwer będzie wysyłał plik ale muszę po pierwsze wiedzieć jak ten plik wysłać i jakie polecenia dołożyć. Wątpię by pliki, np chaucer16k.ino wysyłające po prostu dane bez żadnych rozkazów ani innych operacji służyły do ładowania flasha, mylę się?

    Dodano po 17 [minuty]:

    Doczytałem, wychodzi na to, że za pomocą avrdude (stk500) powinno udać się zaprogramować procesor, sprawdzę niedługo. Tylko co z tą diodą, wygląda jakby program w kółko się resetował.
  • #2 20081468
    bart-projects
    Poziom 29  
    Jak wgrałes sam bootloader i pod adresem $00 nie ma programu głównej aplikacji to jest to normalne zjawisko.

    uC ma ustawiony Reset Vector pod adres zależny od wielkosci bootloadera i tam skacze na początku po uruchomieniu. Normalnie bootloader przez jakiś czas sprawdza czy chcesz wgrać nowy soft i jesli nie to wykonuje skok pod adres $00.
    Tam nie ma softu tylko same $FF i uC po nich "jedzie" aż dojedzie do adresu gdzie napotka kod bootloadera i sprawa się powtarza.
    Jak wgrasz soft aplikacji to on potem trzyma uC np w petli While(void) więc już do bootloadera nie dojedzie.

    Wyjątkiem sa bootloadery uruchamiane z jakiegoś przycisku przy boot. Te mogą czekać.

    Jest też mozliwość, z której ostatnio korzystam, wgrać programatorem zarazem soft aplikacji jak i bootloader za jednym zamachem. Ma to plusy i minusy. Plus to oczywiście predkośc operacji. Minus to to, że wgrywając aplkikację przez bootloader od razu testujesz czy on działa a tu tego kroku nie ma.
  • #3 20082049
    Karol966
    Poziom 31  
    Dzięki za odpowiedź. Od razu narodziło się nowe pytanie, w jaki sposób połączyć oba programy (bootloader + docelowy program)? Da się to zrobić jakoś wygodnie czy należy używać jakiś komend w wierszu poleceń? w 2013 roku TMF napisał tak:
    tmf napisał:
    Połączyć można np. programem srecord, można reż ręcznie (wystarczy usunąć ostatni rekord IntelHex i dołączyć drugiego hexa. Wtedy wczytujesz wszystko za jednym razem.

    https://www.elektroda.pl/rtvforum/topic2603384.html#12495285 nic się nie zmieniło do tej pory? To pytanie bardziej na przyszłość bo obecnie mam bardziej przyziemne problemy:

    1) Jak powinny zostać ustawione segmenty pamięci, czy to poprawne ustawienie? Pobieranie plików z serwera przez SIM868 do Optiboot na Atmega328PB

    2) Dodałem polecenie do Microchip Studio (external tools) ale bootloader nie odpowiada, co jest zgodnie z ciągłym sygnalizowaniem jego startu:
    Cytat:
    avrdude.exe: Version 6.3, compiled on Sep 17 2016 at 19:40:34
    Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
    Copyright (c) 2007-2014 Joerg Wunsch

    System wide configuration file is "G:\_PROGRAMOWANIE\avrdude\avrdude.conf"

    Using Port : \\.\COM16
    Using Programmer : arduino
    Overriding Baud Rate : 115200
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 1 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 2 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 3 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 4 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 5 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 6 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 7 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 8 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 9 of 10: not in sync: resp=0x32
    avrdude.exe: ser_recv(): programmer is not responding
    avrdude.exe: stk500_recv(): programmer is not responding
    avrdude.exe: stk500_getsync() attempt 10 of 10: not in sync: resp=0x32

    avrdude.exe done. Thank you.


    Polecenie:
    Cytat:
    -C "G:\_PROGRAMOWANIE\avrdude\avrdude.conf" -v -v -v -p atmega328pb -c arduino -P\\.\COM16 -b 115200 -D -U flash:w:$(TargetDir)$(TargetName).hex:i


    3) Zatem do sedna problemu, skoro bootloader ciągle jest resetowany przez WDT, zapewne za jego uruchomienie odpowiada polecenie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    A jego reset jeśli dobrze analizuję kod, następuje w funkcji:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    To jak ma działać normalnie urządzenie z wgranym tylko bootloaderem? Ciągły reset bootloadera nie pozwala na wgranie flasha.
  • #4 20082212
    mpier
    Poziom 29  
    Witam,
    pewnie zależy od przyczyny resetu mikrokontrolera, czy uruchomiony zostanie bootloader, czy właściwy program. Próbowałeś uruchomić układ z wciśniętym resetem w trakcie programowania?

    W projekcie jest (razem z komentarzami) kilka tysięcy linii w plikach .c i .h, z czego samego bootloadera, który może się Tobie przydać, jest kilkanaście linijek. Próbowałeś z takim prostym kodem, programującym np. z RAM?

    Pozdrawiam.
  • #5 20082254
    Karol966
    Poziom 31  
    mpier napisał:
    W projekcie jest (razem z komentarzami) kilka tysięcy linii w plikach .c i .h, z czego samego bootloadera, który może się Tobie przydać, jest kilkanaście linijek. Próbowałeś z takim prostym kodem, programującym np. z RAM?

    Analizuję, niektóre rzeczy od razu wywalam bo rozmywają mi obraz całości (kod jest bardzo uniwersalny a mi na tą chwilę niezbędna jest jedynie obsługa procesora 328PB).

    Próbowałem z resetem. Fabryczne arduino ma połączony pin resetu z konwerterem USB/UART więc może to jest tu problemem ale również może nie powinienem się tym w tej chwili najbardziej przejmować, gdyż tak na prawdę muszę zintegrować optiboota z obsługą SIM8xx.
    Pobrałem projekt oparty o optiboot o nazwie AirBootGSM Zamierzam przerobić go na obsługę swojego modułu GSM - może z tym pójdzie mi szybciej.

    mpier napisał:
    może się Tobie przydać, jest kilkanaście linijek

    No właśnie, ten bootloader bazuje na okrojonej wersji STK500v1 a ja w zaszadzie powinienem tą okrojoną wersję jeszcze bardziej okroić bo nie potrzebne mi są większości tych poleceń:
    Cytat:

    #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'
    #define STK_SW_MAJOR 0x81 // ' '
    #define STK_SW_MINOR 0x82 // ' '

    Pytanie czy w ogóle jest sens bazować na jakiejkolwiek kompatybilności z STK500 a skorzystać jedynie z:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    mpier napisał:
    Próbowałeś z takim prostym kodem, programującym np. z RAM?
    Jeszcze nie. Masz na myśli krótki program, który zaprogramuje mi kawałek dowolnej pamięci by sprawdzić czy chociażby podstawy działają?
  • #6 20082634
    mpier
    Poziom 29  
    Ten krótki program, to będzie praktycznie wszystko. Fragment który wystawiłeś nie jest potrzebny. Zajrzyj do dokumentacji od avr/boot.h.
  • #7 20095681
    Karol966
    Poziom 31  
    mpier napisał:
    Ten krótki program, to będzie praktycznie wszystko.


    Rozumiem, popatrzyłem w różne bootoladery i faktycznie są obudowane całą masą różnych zabezpieczeń/ komunikacji. Czyli wychodzi na to, że wystarczy dosłownie kilka linii by zapisać nową zawartość do flasha. Załóżmy więc, że zaczynam od samego początku, korzystając z książki Tomka:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    SPM_PAGESIZE jest stałą, pytanie jak mam obliczać adres strony dysponując czystym plikiem HEX?
    Pobieranie plików z serwera przez SIM868 do Optiboot na Atmega328PB
    Tu kawałek pliku (jakiś przypadkowy hex z pulpitu, pewnie coś z arduino odczytane):
    Cytat:
    :100000000C9458000C9480000C9480000C94800098
    :100010000C9480000C9480000C9480000C94800060
    :100020000C9480000C9480000C9480000C94800050
    :100030000C9480000C9480000C9480000C94800040
    :100040000C9417060C9480000C94E5050C94BF05E5
    :100050000C9480000C9480000C9480000C94800020
    :100060000C9461060C94800000000000250028001C
    :100070002B00040404040404040402020202020229
    :10008000030303030303010204081020408001025C

    Adres pierwszego bajta do zapisu to 0000 (pierwsza linia), wielkość strony SPM_PAGESIZE dla ATmega328PB to 128 słów (z pliku iom328pb.h) czyli najlepiej pobrać jednokrotnie 256 bajtów (samych danych, bo jeszcze dochodzi składnia pliku :1000000 .... CRC) czyli 16 linii z pliku *.HEX

    Hmm, możliwe że trochę mi się miesza więc spróbuję podsumować to co wiem, mam nadzieję że się nie mylę:
    - pobieram z serwera jednorazowo 16 linii (rekordów?) z pliku HEX, to jest 16 * ( 5 + 16 + 1) bajtów =352 bajty danych (AT+HTTPREAD=StartByte,ByteSize), gdzie ByteSize = 352 a StartByte będę inkrementował o 352 po odebraniu/ zapisaniu do FLASH'a danych
    - po odczytaniu 352 bajtów z bufora SIM868 wywalam z niego ":10abcd00" oraz CRC (które powinienem koniecznie zweryfikować) , Tworzę w ten sposób bufor z zawartością 256 bajtów danych do zapisania pod adres pierwszej strony pamięci.
    - po zapisie całej strony, ponownie odczytują z SIM868, kolejny kawałek pliku HEX, przygotowuję dane i zapisuję kolejną stronę pamięci.

    Zgadza się?
  • #8 20095929
    mpier
    Poziom 29  
    Linie w pliku hex nie muszą zawierać po 16 bajtów każda a dane nie muszą być ciągłe ani posortowane. Chyba najprościej byłoby użyć pliku binarnego i zapisać go jak leci do pamięci. Dane w pliku możesz łatwo obrobić zaszyfrować, tak jak chcesz.
  • #9 20095949
    Karol966
    Poziom 31  
    mpier napisał:
    Linie w pliku hex nie muszą zawierać po 16 bajtów każda
    ogólnie tak? Bo wszelkie pliki, które podglądałem dla AVR pochodzące z GCC (MS7, wcześniejsze AS7) miały jednak po 16 bajtów w każdej linii pliku Hex.

    O ile plik binarny zdaje się wygenerować można programem hex2bin o tyle nie wiem co z nim dalej? Załadować go jak leci bajt bo bajcie do flash?

    PS. Dlaczego nie można zaznaczyć opcji tworzenia pliku bin w MS7? W ogóle nie ma tej opcji do wyboru tak jak w dawniejszych wersjach AS.

    Dodano po 59 [minuty]:

    Doczytałem, plik bin jest obrazem pamięci flash 1:1 (a co z innymi typami pamięci, np eeprom, ram?)
    Czyli użycie pliku bin byłoby znacznie prostsze, pobieram dla mojego procesora 256 bajtów danych i zapisuję je do bufora strony po czym zapisuję bufor do flash. Zgadza się?
  • #10 20096935
    bart-projects
    Poziom 29  
    Zawsze sa jakieś "cons" i "pro".
    W pliku Hex zawartych jest dużo więcej informacji takich jak adres gdzie dane umieścić i suma kontrolna etc. Jeśli więc w takim AVR chcesz umieścić tylko bootloader na końcu flash pod dalekim od zera adresem to taki Hex na PC`cie zajmuje mniej miejsca niż Bin bo w Bin albo cały obraz pamięci trzeba zapełnić zerami albo odpowiednio poinstruować programator by zaczął od którejś konkretnej strony.

    Im większa pamięć tym bardziej widać róznicę bo na przykład flashowanie takiego tunera satelitarnego czy innych duzych flash`y to może mieć znaczenie jeśli chcesz coś umieścić pod konkretnym adresem.

    Flashując ESP Bin`ami musiasz wklepać "z palca" adresy wszystkich Bin`ów co pewnie mozna by załatwić Hex`em.

    Mam urządzenia które uaktualniam z serwera i rozważałem tego Optiboot`a. Na końcu jednak stanęło na czymś innym.
    Z racji tego, że oprogramowanie to jednak własnośc intelektualna to moje na serwerze leży zaszyfrowane. Urządzenia je sobie pobierają w formie zaszyfrowanej a bootloader je rozszyfrowuje w locie w paczkach po 128 bajtów.
    "Ściąga" znaczy że zapisuje je czasowo na pamięci SPI AT25M02 albo M95M02 (256KB akurat dla Atmega2560/Atmega2561). Bootloader nie musi wtedy obsługiwać internetu a tylko odczyt pamięci po SPI. Soft na pamięci SPI dalej jest zaszyfrowany. Dopiero bootloader go rozszyfrowuje.

    Pamięć SPI wykorzystuję tylko tam gdzie sterowniki nie maja karty SD. Jak mają kartę SD to soft ściągam z serwera na kartę i bootloader czyta kartę.

    Na karcie lub pamięci SPI mozna pozostawić nawet oryginalny zaszyfrowany soft i zrobić opcję "failsafe" czyli jak update sie nie powiedzie to przywracanie softu poprzedniego.
  • Pomocny post
    #11 20097399
    jvoytech
    Poziom 21  
    Dane do zapisania do pamięci FLASH wydobywa się ze skompilowanego pliku ELF, przy pomocy avr-objcopy, zarówno dla pliku HEX i binarnego. Makefile wygenerowany przez MS7 zwiera taki wpis:
    Kod: Text
    Zaloguj się, aby zobaczyć kod

    Wystarczy zduplikować linię i zamienić ihex na binary:
    Kod: Text
    Zaloguj się, aby zobaczyć kod

    Ale trochę szkoda tracić metadane, które mówią pod jakie adresy bajty powinny zostać zapisane. Trzeba więc wyjść z założenia, że binarne zapisujemy startując od zerowego adresu, albo informację trzymać w innym miejscu, a w HEX jest wszystko na tacy.
  • #12 20103078
    Karol966
    Poziom 31  
    jvoytech napisał:
    "...\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "test1.elf" "test1.hex"


    Zrobiłem to w automacie, ale spotkało mnie coś o czym wspomniał bart-projects tzn:
    bart-projects napisał:
    Hex na PC`cie zajmuje mniej miejsca niż Bin bo w Bin albo cały obraz pamięci
    no i gdy nie miałem parametrów z "-R" to mój wsad dla małego procesora miał (nie pamiętam dokładnie) megabajty (1,3 lub 11 MB)
    Pobieranie plików z serwera przez SIM868 do Optiboot na Atmega328PB

    Czy dla maksymalnego rozmiaru booloadera (2024 słowa, 4kB) tak powinny być ustawione segmenty?
    Cytat:
    -Wl,-section-start=.text=0x7000
    czyli dodając nową sekcję, dodałem ją poprzez:
    Cytat:
    .text=0x3800


    Program, który pobierał sobie dane z serwera a staje się bootloaderam jest tym samym programem a jedyne zmiany jakie jak dotąd poczyniłem są takie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Mam tam przerwanie od timera1, piszę o tym ponieważ program nie działa (wygląda na to jakby nie startował) a został on umieszczony faktycznie pod właściwym adresem:
    Cytat:
    :106FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
    :107000000C947C380C94A0380C94A0380C94A038C4
    :107010000C94A0380C94A0380C94A0380C94A03890
    :107020000C94A0380C94A0380C94A0380C94A2387E
    :107030000C94A0380C94A0380C94A0380C94A03870
    :107040000C94A0380C94A0380C947B390C94A03884
    :107050000C94A0380C94A0380C94A0380C94A03850
    :107060000C94A0380C94A0380C94A0380C94A03840
    :107070000C949E390C94A0380C94A0380C94A03831
    :107080000C94A0380C94A0380C94A0380C94A03820
    :107090000C94A0380C94A0380C94A0380C94A03810
    :1070A0000C94A0380C94A0380C94A0380C94A03800
    :1070B0000C94A03827C00D6B6F6E696563207A61F0
    :1070C00070697375207374726F6E79206E723A00F6
    :1070D0000D7374617274207A6170697375207374B2
    :1070E000726F6E79000D737461727420626F6F74C9
    :1070F0006C6F61646572000011241FBECFEFD8E091
    itd

    A od adresu 0 są same 0xFF, o czym zapomniałem?

    Dodano po 4 [minuty]:

    No to już chyba wiem, nie działa przerwanie od timera, wywaliłem na chwile ich włączenie (jeszcze zapomniałem o przerwaniu od UARTA) i zadziałał zapis strony. Jak zatem przywrócić wektory tych dwóch przerwań (uart1, Timer1 i ew uart0)?

    Dodano po 8 [minuty]:

    No i kolejny update, znalazłem kilka opinii, że przerwania w bootloaderze to nic dobrego (bez większego wyjaśniania dlaczego? ale od osób na avrfreaks raczej ze sporym zasobem wiedzy) a jednak w książce @tmf jest wręcz opisane jak to zrobić by przywrócić wybrane przerwania (intvectortable_case1.c) Przykład:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    I teraz mam zgryz co robić? Przerabiać program by walić przerwania? No ale kurcze, timer służy mi po to by nie było _delay'ów oraz wprowadza timeouty przy obsłudze komunikacji z modułem SIM868 a w przerwaniu odbiornika UART obsługuję bufor kołowy. Jak to zastąpić?
  • #13 20103308
    tmf
    VIP Zasłużony dla elektroda
    Karol966 napisał:
    No i kolejny update, znalazłem kilka opinii, że przerwania w bootloaderze to nic dobrego (bez większego wyjaśniania dlaczego? ale od osób na avrfreaks raczej ze sporym zasobem wiedzy) a jednak w książce @tmf jest wręcz opisane jak to zrobić by przywrócić wybrane przerwania (intvectortable_case1.c)

    A cóż takiego strasznego się wydarzy jeśli włączysz przerwania w bootloaderze? Jeśli się wie co się robi to nie ma problemu.
    Problem pojawia się tylko jesli MCU nie ma oddzielnej tabeli wektorów przerwań dla bootloadera i aplikacji. Wtedy może być kłopot, bo jeśli skasujesz stronę z IVT to przerwania wylecą w kosmos. Więc trzeba to ogarnąć. Natomiast w nowszych prockach masz możliwość przeniesienia IVT w obszar bootloadera, więc bezpiecznie można korzystać z przerwań, z kolei aplikacja ma własne IVT.
    BTW, ten przykład z książki raczej ilustruje skrócenie IVT w celu oszczędzania pamięci. Jeśli MCU ma wiele przerwań to IVT potrafi mieć pokaźny rozmiar. Znowu w nowszych AVR możesz skorzystać z trybu compact i zredukować IVT.
    Karol966 napisał:
    No ale kurcze, timer służy mi po to by nie było _delay'ów oraz wprowadza timeouty przy obsłudze komunikacji z modułem SIM868 a w przerwaniu odbiornika UART obsługuję bufor kołowy. Jak to zastąpić?

    No to sam sobie odpowiedziałeś - jak widzisz ortodoksyjne podejście do pewnych rzeczy prowadzi do absurdów.
  • #14 20103324
    jvoytech
    Poziom 21  
    Karol966 napisał:
    Zrobiłem to w automacie, ale spotkało mnie coś o czym wspomniał bart-projects tzn:
    bart-projects napisał:
    Hex na PC`cie zajmuje mniej miejsca niż Bin bo w Bin albo cały obraz pamięci
    no i gdy nie miałem parametrów z "-R" to mój wsad dla małego procesora miał (nie pamiętam dokładnie) megabajty (1,3 lub 11 MB)

    Rozmiar Hex będzie większy od Bin gdy dane do wgrania zaczynają się od zerowego adresu. Np. 2kB które powinny być umieszczone zaczynając od adresu 0, to w Bin będzie to tylko 2kB, a w Hex dojdzie CRC, adresy docelowe i dodatkowo kodowanie w ASCII. Ale gdy chcemy wgrać 2kB zaczynając od adresu np. 0x7000 to lepszy będzie Hex bo potrafi "ominąć" pierwsze 0x7000 i przejść do sedna. Mógłbyś nazwać plik "bootloader_0x7000.bin" i miałby tylko 2kB ale pozostaje pytanie jak to będą obsługiwać narzędzia? Avrdude akurat potrafi wgrać surowe dane pod konkretne miejsce, tylko że trzeba to napisać w parametrach bo np. po nazwie nie wydedukuje tego bo i dlaczego miałby to robić. W Hex albo ELF jest wszystko jasne.

    Dodatkowo opcja "-R" usuwa podane sekcje, które zostały zadeklarowane w kodzie, dzięki temu możesz sobie wywołać wielokrotnie avr-objcopy i sekcje ".eeprom", ".fuse", ".lock", ".bootloader", etc. porozdzielać do osobnych plików. To również może wpłynąć na rozmiar pliku Hex lub Bin.

    Ty nie musisz koniecznie przesyłać plik Hex do twojego urządzenia, możesz słać surowe bajty, skompresowane, z lepszym CRC, etc. Tak musisz sobie skonstruować ramkę, żeby dane trafiły pod odpowiedni adres w FLASH. Hex to jedynie do plików na PCecie.

    Karol966 napisał:

    Cytat:
    :106FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
    :107000000C947C380C94A0380C94A0380C94A038C4

    A od adresu 0 są same 0xFF, o czym zapomniałem?

    Ja tam nie widzę adresu 0 tylko 0x6ff0. Wydaje mi się, że to była konwersja z pliku Bin do Hex i ta linia została zostawiona. Po czyszczeniu FLASH komórki przyjmują wartość FF, więc spokojnie tą linię możesz usunąć. W każdym bądź razie programator powinien ją zignorować.
  • #15 20103328
    Karol966
    Poziom 31  
    Udało mi się zapisać pierwszą stronę pamięci, potem modyfikowałem program i chciałem zapisać kilka stron - za każdym razem zapisywała się tylko 1 strona poprawnie aż w końcu zapisuję tylko pierwszą stronę i to błędnymi danymi. Długa noc przede mną...

    wrzucam w zasadzie cały testowy kod, przepraszam za bałagan bo jest w nim pełno zakomentowanych kawałków kodu z poprzednich prób. Coś robię ostro nie tak jak trzeba. Proszę o pomoc.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Dodano po 3 [minuty]:

    jvoytech napisał:
    a tam nie widzę adresu 0 tylko 0x6ff0.
    No ale przecież mówiłem o umiejscowieniu bootloadera, który miał się znaleźć od adresu 0x7000. Ponadto bootloader w końcu startuje (powyższe posty) tylko nie działa jeszcze poprawnie.
  • #16 20103392
    mpier
    Poziom 29  
    Czemu służą te komplikacje z tymi __init*? Przecież jeżeli chcesz używać przerwań, to po prostu na początek nie usuwaj tablicy wektorów i całej reszty z której rezygnujesz przy opcji -nostartfiles. Wtedy kod będzie wyglądał tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #17 20103394
    Karol966
    Poziom 31  
    mpier napisał:
    nie usuwaj tablicy wektorów i całej reszty z której rezygnujesz przy opcji -nostartfiles.

    tmf napisał:
    skrócenie IVT w celu oszczędzania pamięci


    Kombinuję dalej, w tabeli dane2 mam wrzucną zawartość hex'a programu, który miga diodą z delay'em (mało ważne), ok 230bajtów, bootloader ładuje mi tylko 1 stronę:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Dodano po 20 [minuty]:

    Ok, gdy zapisuję drugą stronę to muszę zrobić: boot_page_write_safe(SPM_PAGESIZE); i się zapisała poprawnie. Program startuje ale nie działa/ nie mruga diodą a odczyt zawartości flash jest taki sam po uruchomieniu bootloadera jak ten mały HEX. Szukam dalej.

    Dodano po 14 [minuty]:

    A jednak działa (testowałem na starszej wersji pcb, tu dioda wymaga użycia dwóch pinów procka).

    Nooo, dzieje się :)
  • #18 20105452
    Karol966
    Poziom 31  
    Problem z przerwaniami a raczej ich brakiem był związany, wg mojej wiedzy/ obserwacji z nieprawidłowym przeniesieniem tablicy wektorów przerwań.
    Same instrukcji wg książki:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Nie działały, trafiłem na podobny temat i zrobiłem tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    I teraz przerwania działają ale po moich modyfikacjach program przestał działać. Czy bezpiecznie jest skakać do aplikacji czy jednak resetować procesor przez WDT? Przenieść z powrotem tablicę wektorów przerwań przed uruchomieniem app?
  • #19 20105529
    tmf
    VIP Zasłużony dla elektroda
    Karol966 napisał:
    ie działały, trafiłem na podobny temat i zrobiłem tak:

    Pamiętaj, że niektóre konfiguracje są zależne czasowo - masz np. 4 takty na dokonanie zmian. To wymaga włączenia optymalizacji.
    Karol966 napisał:
    Czy bezpiecznie jest skakać do aplikacji czy jednak resetować procesor przez WDT? Przenieść z powrotem tablicę wektorów przerwań przed uruchomieniem app?

    Lepiej resetować procek przez WDT lub soft reset (o ile jest). Reset przeniesie też IVT w domyślne miejsce.
  • #20 20117855
    Karol966
    Poziom 31  
    Bootloader startuje zawsze jako pierwszy, sprawdza status aplikacji i jeśli trzeba dokonuje aktualizacji (treść aplikacji jest w pamięci RAM programu bootloadera dla testów), następuje restart i aplikacja startuje. Po wywołaniu aktualizacji z poziomu aplikacji w taki sposób:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    startuje bootloader i ciągle się resetuje (ustawiony bit WDRF w MCUSR) a na samym początku programu bootloadera wyłączam wdt (wdt_disable();)
    Gdzie leży problem?

    PS. Kiedy odblokować rww? Wydaje mi się, że nie po zapisie pojedynczej strony a po zakończeniu ładowania wszystkich stron.
    PS2. Czy to ważne aby przywracać stan sreg oraz włączać przerwania po skończonej pracy bootloadera (SREG = sreg;) skoro aplikacja przerwania sobie konfiguruje/ uruchamia samodzielnie?[/film]
  • #21 20126536
    Karol966
    Poziom 31  
    Zrobiłem szybki test, aplikacja która wywoływała bootloader poprzez wdt_enable(WDTO_15MS); zamieniłem na wdt_enable(WDTO_250MS); bo ewidentnie po tym procesor ciągle był resetowany przez WDT, ustawiony bit WDRF mimo że bootloader jako trzecia z instrukcji w main ma wdt_disable();

    Dodałem więc:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Na podstawie innego bootloadera i zadziałało - czemu zatem nie działało wdt_disable()? Zmieniałem również czas startu procesora na 4.1ms - bez efektu.

Podsumowanie tematu

Dyskusja dotyczy implementacji bootloadera Optiboot na mikrokontrolerze Atmega328PB, który umożliwia pobieranie i programowanie aplikacji z serwera za pomocą modułu SIM868. Użytkownik napotkał problemy z resetowaniem mikrokontrolera przez watchdog (WDT) oraz z integracją bootloadera z aplikacją. Wskazano na konieczność odpowiedniego ustawienia segmentów pamięci oraz na różnice między plikami HEX a binarnymi, które wpływają na proces programowania. Uczestnicy dyskusji podzielili się doświadczeniami związanymi z przenoszeniem tablicy wektorów przerwań oraz z wyłączaniem WDT. Zasugerowano również, że pliki binarne mogą być prostsze w użyciu, ale pliki HEX zawierają więcej informacji, co może być korzystne w niektórych przypadkach.
Podsumowanie wygenerowane przez model językowy.
REKLAMA