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

Porównanie i konwersja plików BIN i HEX – wyświetlanie, edycja oraz programowanie układów AVR

Karol966 05 Paź 2022 14:41 2484 15
REKLAMA
  • #1 20222468
    Karol966
    Poziom 31  
    Posty: 2041
    Pomógł: 83
    Ocena: 650
    Plik hex zawiera dane szesnastkowe, intel hex poza tym zawiera dane zgodnie ze standardem:
    -znacznik rozpoczynający ":"
    - liczba bajtów (dla AVR GCC zwykle widać tam 16 bajtów czyli liczbę "10" hex)
    - adres, zwykle widać jak każda kolejna linia jest o 16 bajtów "dalej" umieszczona w pamięci
    - dane (czyli te zwykle 16 bajtów). W polu danych widać od razu wszelkie kody ascii znaków używanych w programie no i całą masę pozostałych danych
    - CRC

    Natomiast z tego co powszechnie się czyta, plik binarny to bezpośredni obraz pamięci jak leci, baj po bajcie. No OK, czyli programator używając pliku HEX musi konwertować wszelkie odebrane bajty danych do postaci binarnej? No a czym zatem jest plik hex? Przecież mają dane szesnastkowe wprawiony programista niemal w locie konwertuje obie połówki (po 4 bity) do postaci binarnej wiec w czym rzecz?

    Jak można porównać dwa pliki binarne? W czym je wyświetlić? Jeśli plik otwieram w programie np do programatora CH341 to widzę w zasadzie te same dane jakie widać w wersji hex tego samego pliku odpalonego w notepadzie++
    Być może gdzieś się zakręciłem i odpaliłem nie te pliki co trzeba ale wydawało mi się, ze plik bin przekonwertowany https://iamkate.com/code/binary-file-viewer/ miał inną końcówkę niż plik hex (oba z tego samego projektu z AS7).

    Jak fizycznie wyglądają dane pliku binarnego? Przecież gdyby to był system dwójkowy (bin) to były by w pliku same zera i jedynki, prawda?

    Czego tu nie rozumiem? Chcę napisać bootloader, który pobierze sobie plik z firmware z serwera. Plik HEX pobieram a z plikiem bin mam "dziwne" problemy ale może po prostu czegoś banalnego nie rozumiem.
  • REKLAMA
  • Pomocny post
    #2 20223012
    Sareph
    Poziom 24  
    Posty: 638
    Pomógł: 65
    Ocena: 378
    Karol966 napisał:
    czyli programator używając pliku HEX musi konwertować wszelkie odebrane bajty danych do postaci binarnej?
    No tak.

    Karol966 napisał:
    Jak można porównać dwa pliki binarne? W czym je wyświetlić?
    W HxD na przykład.

    Karol966 napisał:
    Jak fizycznie wyglądają dane pliku binarnego?
    Dokładnie tak samo jak w pamięci. To pytanie to jest taka podstawowa podstawa, że ja chyba nie rozumiem o co to pytanie.

    Karol966 napisał:
    Przecież gdyby to był system dwójkowy (bin) to były by w pliku same zera i jedynki, prawda?
    Nie. Jest jeszcze coś takiego jak reprezentacja danych. Bo w gruncie rzeczy są tam same zera i jedynki. Nawet te pliki hex to same zera i jedynki, tylko o ograniczonym zakresie.

    Karol966 napisał:
    ale może po prostu czegoś banalnego nie rozumiem.
    Najpewniej, bo żeby wgrać plik bin do pamięci to w sumie wystarczy z grubsza memcpy().
  • REKLAMA
  • Pomocny post
    #3 20223119
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2206
    @Karol966 Plik binarny zawiera dane z FLASH, które lecą po kolei - bajt po bajcie. Czyli jeśli np. FLASH ma 8 kB, to jego zrzut w postaci binarnej to będzie 8kB danych (może być mniej, ale wtedy plik zawiera tylko początkową zawartość pamięci). Natomiast jak sam zauważyłeś plik w formacie IntelHEX ma złożoną strukturę. W ramach jednej linii zawiera dane binarne do załadowania do pamięci, ale ma także specjalne polecenia określające adres od którego te dane mają być ładowane. W efekcie w IntelHEX oprócz danych programu masz także pewne elementy dodatkowe, oprócz modyfikatorów adresu także np.. CRC. W efekcie plik binarny zawiera zrzut ciągłego obszaru pamięci, natomiast IntelHEX może zawierać informacje o nieciągłych obszarach, zawierających "dziury".
    Stąd też jeśli np. program mieści się pod adresami 0-100 i potem np. 1000-1100, to bin musi mieć długość co najmniej 1100 bajtów (zawiera też nieistotne dane z tej dziury), z kolei w hex możesz reprezentować dane z adresów 0-100 i 1000-1100. W obu plikach same dane są oczywiście w postaci binarnej (lub heksadecymalnej, ale to tylko inna reprezentacja tych samych danych).

    Dodano po 1 [minuty]:

    Karol966 napisał:
    Plik HEX pobieram a z plikiem bin mam "dziwne" problemy ale może po prostu czegoś banalnego nie rozumiem.

    Dane z pliku bin po prostu zapisujesz po kolei w pamięci - niestety bootloader musi w tym przypadku dokładnie wiedzieć od jakiej lokacji rozpocząć zapis, bo z pliku bin to nie wynika.
  • #4 20223179
    Karol966
    Poziom 31  
    Posty: 2041
    Pomógł: 83
    Ocena: 650
    tmf napisał:
    Plik binarny zawiera dane z FLASH, które lecą po kolei - bajt po bajcie
    no właśnie. Rozumiem to. Może mój problem polega na tym, że nie rozumiem różnicy między hexem a bonem (poza dodatkowymi danymi o których wiemy). Czy jeśli z pliku Intel Hex usunę wszystko co nie jest danymi a potem zapisze go od początku do jego końca do pamięci procesora to poprawnie zaprogramuje procesor?

    Druga sprawa, jeśli plik bin pobiore np z serwera a potem uartem bajt po bajcie wyśle do terminala ale wcześniej każdy bajt przekonwertuje np za pomocą utoa(bajt_n,bufff,16) to zobaczę w terminalu dokładnie te same dane jak w alternatywnym pliku Hex?

    To że pliku bin nie można odczytać w popularnych edytorach jest zrozumiałe (zawiera dane w zakresie 0-255). No ale właśnie,czy zawsze to są po kolei bajty? Czy nie jest też tak że plik binarny to tak na prawdę ciąg zer i jedynek w ilości rozmiar_pliku_w_bajtach*8?

    I ostatnie pytanie, jeśli ładuje bufor strony pamięci korzystając z pliku Hex to oczywiście pilnuje adresu a potem zapisuje bajt po bajcie tak jak leci, a jak robię to samo z użyciem pliku bin to również lecę bajt po bajcie i choć w terminalu nie zobaczę nic poza krzakami to zapisze do bufora strony te same dane co w przypadku czytelnego hexa?
  • #5 20223256
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2206
    Karol966 napisał:
    Czy jeśli z pliku Intel Hex usunę wszystko co nie jest danymi a potem zapisze go od początku do jego końca do pamięci procesora to poprawnie zaprogramuje procesor?

    Nie, bo te dodatkowe informacje, zawierają np. dane gdzie te bajty mają zostać zapisane. Także, czasami, dla najprostszych plików hex, zawierających liniowe obszary pamięci to zadziała (o ile znasz adres początkowy), to w przypadku złożonych hexów, zawierających poprzerywane obszary pamięci to nie zadziała, bo dane znajdą się pod niewłaściwymi adresami.
    Karol966 napisał:
    Druga sprawa, jeśli plik bin pobiore np z serwera a potem uartem bajt po bajcie wyśle do terminala ale wcześniej każdy bajt przekonwertuje np za pomocą utoa(bajt_n,bufff,16) to zobaczę w terminalu dokładnie te same dane jak w alternatywnym pliku Hex?

    Prawie. Zobaczysz tylko element hexa - zawierający dane programu.
    Karol966 napisał:
    To że pliku bin nie można odczytać w popularnych edytorach jest zrozumiałe (zawiera dane w zakresie 0-255). No ale właśnie,czy zawsze to są po kolei bajty? Czy nie jest też tak że plik binarny to tak na prawdę ciąg zer i jedynek w ilości rozmiar_pliku_w_bajtach*8?

    Zawsze są to kolejne bajty. Różnica jest taka, że w hex te kolejne bajty są zapisane w postaci ASCII, czyli jeden bajt z bin zamieniany jest na dwa znaki z zakresu 0..F.
    Karol966 napisał:
    I ostatnie pytanie, jeśli ładuje bufor strony pamięci korzystając z pliku Hex to oczywiście pilnuje adresu a potem zapisuje bajt po bajcie tak jak leci, a jak robię to samo z użyciem pliku bin to również lecę bajt po bajcie i choć w terminalu nie zobaczę nic poza krzakami to zapisze do bufora strony te same dane co w przypadku czytelnego hexa?

    Tak, zapiszesz to samo. Oczywiście zakładając, że z hex robisz konwersję poszczególnych znaków do bin. Plik hex jest plikiem tekstowym, więc zapisane wartości w kodzie ASCII trzeba zamienić na bin.
  • #6 20223317
    Karol966
    Poziom 31  
    Posty: 2041
    Pomógł: 83
    Ocena: 650
    tmf napisał:
    zawierających liniowe obszary pamięci to zadziała
    no właśnie o taki przypadek mi chodziło. Przeglądając proste pliku hex zauważyłem, że adresy zmieniały się zwykle co 16 bajtów więc było liniowo. Czyli odpowiedź na wcześniej zadane pytanie będzie jednak TAK? :)

    tmf napisał:

    więc zapisane wartości w kodzie ASCII trzeba zamienić na bin.

    No i chyba w końcu dochodzimy do sedna mojego braku zrozumienia. Czyli jednak pliku hex nie można zapisać prosto bajt po bajcie pod właściwy adres (uprzednio wycinając wszystkie dodatki, które zawiera format Intel hex) lecz wcześniej trzeba zrobić konwersję do bin, dobrze rozumiem?

    Teraz idąc dalej, dlaczego trzeba zrobić ta konwersję? Jeśli pierwszy bajt danych z pliku hex dla adresu 0 wynosi C9 to przecież jego reprezentacja binarna to po prostu 11001001 ale to tylko reprezentacja a fizycznie to 0xC9 to to samo co 0b11001001 więc po co robic konwersję pliku danych z pliku hex do bin? A może o inną konwersję chodzi? To jest właśnie mój problem. Być może źle zadałem początkowo pytanie.
  • REKLAMA
  • #7 20223321
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2206
    Karol966 napisał:
    Teraz idąc dalej, dlaczego trzeba zrobić ta konwersję? Jeśli pierwszy bajt danych z pliku hex dla adresu 0 wynosi C9 to przecież jego reprezentacja binarna to po prostu 11001001 ale to tylko reprezentacja a fizycznie to 0xC9 to to samo co 0b11001001 więc po co robic konwersję pliku danych z pliku hex do bin? A może o inną konwersję chodzi? To jest właśnie mój problem. Być może źle zadałem początkowo pytanie.

    Nie, C9 w pliku hex to nie to samo co 0xC9 w zapisie heksadecymalnym. W hex C9 jest w ASCII, a więc są to dwa znaki - 'C' i '9'. Zapisując do flash musisz dokonać konwersji z tego zapisu na zapis binarny.
  • #8 20223362
    Karol966
    Poziom 31  
    Posty: 2041
    Pomógł: 83
    Ocena: 650
    tmf napisał:
    Nie, C9 w pliku hex to nie to samo co 0xC9 w zapisie heksadecymalnym. W hex C9 jest w ASCII, a więc są to dwa znaki - 'C' i '9'. Zapisując do flash musisz dokonać konwersji z tego zapisu na zapis binarny.


    Pobierając plik hex z serwera i wysyłając go w terminalu widzę dane... o kurcze, no właśnie, widzę dane wyświetlane w ascii:
    Porównanie i konwersja plików BIN i HEX – wyświetlanie, edycja oraz programowanie układów AVR

    Czyli faktycznie C9 to dwa osobne znaki zatem czy chodzi o to, ze jeden ma kod ascii 0x43 a drugi 0x39 i takie kody widzę gdy przełączyłem wyświetlanie odebranych danych w formie hex. Zatem należy wykonać konwersji odebranych danych z pliku hex, dla przykładu C9(ascii) na format 0xC9. Zastanawiam się jak to zrobić, jest późno i głowa już nie pracuje. Szukając podobnego zagadnienia znalazłem ten wątek: https://stackoverflow.com/questions/8551383/h...-a-hexadecimal-string-to-a-binary-string-in-c chciałbym to prosto zrealizować.
    Jedyne co przychodzi mi do głowy to faktycznie lookup table, wówczas dla indeksu 43 w tabeli zostanie odczytana liczba 0x0C, a dla kodów z zakresu 0x30-0x39 po prostu zwrócona zostanie liczba pomniejszona o 0x30, następnie pierwsza część zostanie przesunięta o 4 pozycje oraz dodana druga/ młodsza część. Zwracając wartość z tabeli odwoływał bym się do indeksu pomniejszonego o 0x41 i przyjął tylko wielkie litery.

    Zrobiłem to tak, wynik wydaj się być poprawny:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    <script src="//onlinegdb.com/embed/js/bagOiS_9p?theme=dark"></script>

    Dodano po 16 [minuty]:

    Może lepiej teraz:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    https://onlinegdb.com/YAVbkGR_A
  • Pomocny post
    #9 20225236
    jvoytech
    Poziom 22  
    Posty: 364
    Pomógł: 61
    Ocena: 136
    możesz użyć funkcji strtol do konwersji liczby szesnastkowej na int-a, np. tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    wracając do pierwszego postu, liczba bajtów w linii może być różna, najczęściej 16 ale 32 i więcej też się zdarza (max to 255), więc uważaj
  • REKLAMA
  • #10 20225334
    Karol966
    Poziom 31  
    Posty: 2041
    Pomógł: 83
    Ocena: 650
    jvoytech napisał:
    możesz użyć funkcji strtol do konwersji liczby szesnastkowej na int-a, np. tak:


    Dzięki za sugestię. Elegancko to wygląda. W symulatorze działa poprawnie. W swoim kodzie dodałem na szybko w imię testu tylko taką komendę:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a rozmiar programu wzrósł z 3072 do 3932 bajtów więc na pewno nie mogę sobie pozwolić na użycie tej funkcji.

    ________________________________________________________

    Jak tylko dojdę dlaczego moduł GSM po pobraniu pliku *.bin z serwera się resetuje to wrócę do sprawdzenia jakie dane pobiera (przekonwertuję je do hexa) i porównam z danymi z pliku *.hex
  • Pomocny post
    #11 20225623
    jvoytech
    Poziom 22  
    Posty: 364
    Pomógł: 61
    Ocena: 136
    Karol966 napisał:
    a rozmiar programu wzrósł z 3072 do 3932 bajtów więc na pewno nie mogę sobie pozwolić na użycie tej funkcji.

    Aha, nie wiedziałem, że dekodowanie robisz na MCU. To może zrób tak, że MCU komunikuje się z serwerem dwukrotnie i na początku przy pierwszym zapytaniu pobiera metadane odnośnie wsadu, wielkość firmware, adres startowy w FLASH, CRC całego wsadu, a potem pobiera dane binarnie szybko bez żadnych konwersji?

    Ogólnie plikiem wyjściowym jest ELF. W nim jest wszystko, dane dla FLASH, symbole debugera, miejsca w kodzie i odpowiadające im instrukcje w kodzie źródłowym. To z niego wydobywa się pliki BIN albo HEX, np. tak:
    Kod: Text
    Zaloguj się, aby zobaczyć kod

    Np. avrdude łyka wszystko, później i tak komunikuje się po swojemu z programatorem. BIN otwiera jako "fopen(.., "rb")" lub "ifstream(.., ios::binary)" i śle surowe dane do programatora mówiąc mu wcześniej żeby zaczął zapisywać od adresu 0 domyślnie (chyba że użytkownik poda inaczej). HEX otwiera jako tekstowe ale musi je lekko obrobić, czyli zamienić np. napis "FF" (2bajty) na bajt 255, i dopiero te dany posłać do programatora pod adres odczytany z tegoż pliku.

    Różnica między binarnym a tekstowym jest taka, że w binarnym znajdują się wszystkie wartości z zakresu 0-255 i powinny być otwierane w trybie "rb" lub "ios::binary", żeby nie było czasem jakiejś automatycznej konwersji znaków końca linii "\n", "\r\n". Nie powinno się je wysyłać do terminala bo terminal interpretuje bajty i może się poprzestawiać, np. zmieni się kolor czcionki, cursor się wyłączy, etc. Do oglądania plików binarnych w terminalu jest kilka programów:
    1. "hexyl" - fajny z kolorowaniem znaków
    2. "xxd" - mój ulubiony, można wyświetlić tekstowo bajty w hex albo binarnie, lub wygenerować kod C do wklejenia w plik źródłowy
    3. "od" - stary ale jary
    4. "hexdump" - działa podobnie jak "od"
    5. możesz też pliki binarne zapisywać np. w formacie base64 (komenda "base64 plik.bin"). Mniej zajmuje miejsca bo korzysta z większej ilości drukowalnych znaków alfanumerycznych od HEX ale jak widać odczyt tego już nie jest tak prosty.

    poniżej prosta demonstracja ww. programów:
    Kod: Text
    Zaloguj się, aby zobaczyć kod


    Dodano po 48 [minuty]:

    tmf napisał:
    Nie, C9 w pliku hex to nie to samo co 0xC9 w zapisie heksadecymalnym. W hex C9 jest w ASCII, a więc są to dwa znaki - 'C' i '9'. Zapisując do flash musisz dokonać konwersji z tego zapisu na zapis binarny.

    Takie jeszcze dodatkowe wyjaśnienia z mojej strony. W pliku tekstowym znajduje się napis "C9":
    Kod: Text
    Zaloguj się, aby zobaczyć kod

    w pliku są tam zapisane dwa bajty (każdy 8-bitów) 01000011 i 00111001 (zero/jedynka albo stan niski/wysoki, albo obszar namagnesowany/nie namagnesowany, etc.). Te bity można zaprezentować w postaci hexadecymalnej 0x43, 0x39 co odpowiada w kodzie ASCII znakom alfanumerycznym "C" i "9". Terminal albo inny program graficzny tą sekwencję bitów rysuje w kształcie "C" oraz "9" ale w pliku to są po prostu 0 i 1, nie ważne czy to jest plik tekstowy, czy binarny.

    Znak ASCII "C", który w pliku jest zapisany binarnie 01000011 trzeba zamienić na 1100 (0xC, 12d) i przesunąć o 4 bity w lewo co da nam 1100_0000 (0xC0, 192d), znak ASCII "9" zakodowany w pliku jako 00111001 (0x39, 57d) trzeba zamienić na 1001 (0x9, 9d) i dodać do poprzedniej wartości: 0xC0+0x09=0xC9(201d, 1100_1001b). Tak otrzymany bajt 11001001 (0xC9) można wysyłać do FLASH.

    W pliku binarnym będzie to tylko 1 bajt o bitach 11001001 gotowy do zapisania we FLASH bez żadnych konwersji. Wysłanie go na terminal jest bez sensu ponieważ może dać różne rezultaty. Jeżeli terminal jest skonfigurowany jako utf-8 to nic się nie wydarzy ponieważ jest to tylko część znaku spoza ASCII, jakiś krzaczek lub emoji i terminal będzie oczekiwał na dalsze bajty. W przypadku gdy to nie jest utf-8 to wygląd zależy od strony kodowej, wtedy zobaczymy dziwny znaczek, może cyrylicę, coś z kanji, etc. Dlatego binarnych plików nie śle się na terminal tylko konwertuje każdy bajt na dwa bajty alfanumerycznie (przy pomocy xxd, od, hexdump, hexyl, etc.).
  • #12 20225809
    Karol966
    Poziom 31  
    Posty: 2041
    Pomógł: 83
    Ocena: 650
    jvoytech napisał:
    Aha

    Dziękuje za ogromny wkład w pomoc. Chwilowo zakończyłem wszelkie symulacje i wróciłem do swojego małego procka (ATmega328pb). Moduł SIM868 pobiera plik binarny z serwera do swojej pamięci. Mogę odczytywać jego dowolny wycinek jak i cały na raz (to akurat zbędne chyba, że chciałbym policzyć na początku jego CRC zanim zacznę go ładować do flash'a. Odebrane dane binarne z pamięci modułu GSM wysłałem na port szeregowy w ten sposób:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a powyższą funkcję wywołuję sobie tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Oto dane z terminala wysłane przez procesor (czyli mam już z poziomu procesora swoje upragnione dane binarne/ mój flash do załadowania przez bootloader)
    Cytat:
    file_size=10806
    liczba_ramek=84
    wyrownanie=54
    odczyt czesci numer:0
    dane:
    0c 94 04 02 0c 94 21 02 0c 94 21 02 0c 94 21 02
    0c 94 ad 05 0c 94 21 02 0c 94 21 02 0c 94 21 02
    0c 94 21 02 0c 94 21 02 0c 94 21 02 0c 94 b8 04
    0c 94 21 02 0c 94 21 02 0c 94 21 02 0c 94 21 02
    0c 94 21 02 0c 94 21 02 0c 94 cd 10 0c 94 21 02
    0c 94 21 02 0c 94 21 02 0c 94 21 02 0c 94 21 02
    0c 94 21 02 0c 94 21 02 0c 94 21 02 0c 94 ef 05
    0c 94 3c 11 0c 94 21 02 0c 94 21 02 0c 94 21 02
    odczyt czesci numer:1
    --1
    dane:
    0c 94 21 02 0c 94 21 02 0c 94 21 02 0c 94 21 02
    0c 94 21 02 0c 94 21 02 0c 94 21 02 0c 94 21 02
    0c 94 21 02 0c 94 21 02 0c 94 21 02 0c 94 21 02
    0c 94 21 02 2b 57 44 52 46 00 2b 42 4f 52 46 00
    2b 45 58 54 52 46 00 50 4f 52 46 00 0d 4d 43 55
    53 52 3a 00 0d 52 32 36 38 00 0d 52 32 36 34 00
    0d 43 48 47 20 49 4e 54 00 0d 4d 50 55 20 49 4e
    54 00 0d 52 30 37 37 00 41 54 2b 53 41 50 42 52
    odczyt czesci numer:2
    --1
    dane:
    6f 64 65 64 00 41 54 2b 53 41 50 42 52 3d 32 2c
    31 0d 00 41 54 2b 48 54 54 50 54 45 52 4d 0d 00
    41 54 2b 48 54 54 50 50 41 52 41 3d 43 49 44 2c
    31 0d 00 41 54 2b 48 54 54 50 49 4e 49 54 0d 00
    41 54 2b 53 41 50 42 52 3d 31 2c 31 0d 00 41 54
    2b 53 41 50 42 52 3d 33 2c 31 2c 22 41 50 4e 22
    2c 22 00 41 54 2b 53 41 50 42 52 3d 33 2c 31 2c
    22 43 4f 4e 54 59 50 45 22 2c 22 47 50 52 53 22
    odczyt czesci numer:3
    dane:
    2d 53 4d 53 2d 4f 4b 00 26 69 64 78 3d 00 26 73
    74 61 74 65 3d 00 53 65 70 20 20 31 20 32 30 32
    32 00 26 62 75 69 6c 64 3d 00 26 66 68 76 3d 00
    26 63 73 71 3d 00 26 64 42 48 7a 3d 00 26 73 69
    75 3d 00 26 73 69 76 3d 00 26 76 63 68 67 3d 00
    26 76 62 61 74 3d 00 26 75 74 63 3d 00 26 63 6f
    75 72 73 65 3d 00 26 73 70 65 65 64 3d 00 26 61
    6c 74 69 74 75 64 65 3d 00 26 6c 6f 6e 67 69 74
    odczyt czesci numer:4
    --1
    dane:
    d4 ea 14 e8 d0 93 bc 00 80 91 bc 00 87 ff fc cf
    80 91 b9 00 88 7f 88 30 a9 f7 c0 93 bb 00 10 93
    bc 00 80 91 bc 00 87 ff fc cf 80 91 b9 00 88 7f
    88 31 19 f0 0e 94 74 02 e5 cf df 91 cf 91 1f 91
    08 95 80 93 bb 00 84 e8 80 93 bc 00 80 91 bc 00
    87 ff fc cf 80 91 b9 00 88 7f 88 32 21 f0 80 33
    21 f0 82 e0 08 95 80 e0 08 95 81 e0 08 95 84 e8
    80 93 bc 00 80 91 bc 00 87 ff fc cf 80 91 bb 00


    W końcu widzę czym jest plik binarny a czym plik intel hex. Wyszło na to co podejrzewałem, że binarny majac surowe dane wystarczy wyświetlić konwertując na hexy np za pomocą utoa(bajt_bin,buff,16)); i widzimy wtedy to samo co przedstawia plik hex (w polu danych/ pomijam adresy - przyjmuję, że lecą od 0 do końca pliku jednym ciągiem).

    Dodano po 15 [minuty]:

    jvoytech napisał:
    o może zrób tak, że MCU komunikuje się z serwerem dwukrotnie i na początku przy pierwszym zapytaniu pobiera metadane odnośnie wsadu, wielkość firmware, adres startowy w FLASH, CRC całego wsadu, a potem pobiera dane binarnie szybko bez żadnych konwersji?


    Coś w ten deseń już robię ale że nie jestem specem w gcc to mój kod jest dość obszerny dlatego pierwotny booloader pobiera sobie domyślny program z serwera (stały adres zapisany w pamięci bootloadera) po czym domyślny program już pobiera sobie, jak to nazwałeś, metadane. Wszelkie pobrane informacje o adresie pliki na danym serwerze/ wielkości/ crc itd itp zapisuje w eepromie od końca (przed E2END) i wywołuje bootloader raz jeszcze - wtedy już bootloader wie co ma zrobić. Chciałbym upakować wszystko w 1 pliku ale raczej nie mam szans bo to co mam teraz dla samego pobierania binarki i dzielenie jej na kawałki zajmuje mi ok 3000 bajtów (jest tam trochę danych do debugera/ krótkie teksty dla terminala wiec go odchudzę). Oczywiście będę próbował wszystko upakować w sam program bootloadera. Póki co jestem bardzo zadowolony, że zadziałało pobranie binarki a co ciekawe i dołujące jednocześnie - to działało mi od początku. Po pierwsze myślałem że procesor się resetuje/ wchodzi w dziwny stan wysyłając "dziewne" dane w terminalu a tak się składa, że te teskty ubrane w krzaki były po prostu deklaracjami stringów z pamięci a na moje nieszczęscie wszelkie krytyczne dane właśnie były na początku pamięci:
    Porównanie i konwersja plików BIN i HEX – wyświetlanie, edycja oraz programowanie układów AVR
    Jak widziałem swoje WDRF BORF MCUSR itd to się zmyliłem.
    Drugi temat to zawiechy - zawiechy były przez moje timeouty do odbioru danych w przerwaniu od UARTU, swoją drogą nie wiem dlaczego
    procesor wisi skoro na końcu odczytanego fragmentu pliku binarnego moduł GSM wysyła "OK" a właśnie na to "OK" czekam.

    No nic, jest już dobrze - trzeba posprzątać i odpalić program bootloadera - zintegrować wszystko razem (pobieranie pliku oraz ładowanie do flash - osobno oba programy już działają).
  • Pomocny post
    #13 20226336
    jvoytech
    Poziom 22  
    Posty: 364
    Pomógł: 61
    Ocena: 136
    Karol966 napisał:
    W końcu widzę czym jest plik binarny a czym plik intel hex. Wyszło na to co podejrzewałem, że binarny majac surowe dane wystarczy wyświetlić konwertując na hexy np za pomocą utoa(bajt_bin,buff,16)); i widzimy wtedy to samo co przedstawia plik hex (w polu danych/ pomijam adresy - przyjmuję, że lecą od 0 do końca pliku jednym ciągiem).

    Jeżeli chodzi o funkcję utoa z biblioteki avr_stdlib to własna implementacja może zająć mniej miejsca i jeżeli faktycznie jej potrzebujesz w bootloaderze to może gra jest warta świeczki. Zrobiłem małą próbę:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a oto skrypt do budowania
    Kod: Bash
    Zaloguj się, aby zobaczyć kod

    wynik działania skryptu:
    Kod: Text
    Zaloguj się, aby zobaczyć kod

    te 150 bajtów może się kiedyś przydać.
  • #14 20231162
    Karol966
    Poziom 31  
    Posty: 2041
    Pomógł: 83
    Ocena: 650
    A już tak blisko było, zapisuję do flasha poprawnie 84 strony pamięci, wysypuje mi się na siódmej stronie dla tego, że program szuka w buforze UARTu wystąpienia ciągu "+HTTPREAD:" a ten sam ciąg występuje również w treści danych binarnych jak i jest wysyłany przez moduł GSM. W jednej paczce danych odczytanych za pomocą HTTPREAD dostaję 2 razy ten sam ciąg i przez to program leci w krzaki. Jak sobie z tym poradzić? Myślałem o narzuceniu funkcji oczekiwania na zadaną ilość odebranych bajtów danych w buforze UARTU ale do póki nie odbiorę ich to nie znam długości całej ramki wiec to błędne koło.
  • #15 20233963
    mpier
    Poziom 29  
    Posty: 818
    Pomógł: 153
    Ocena: 141
    Cześć,
    przecież znasz długość odbieranych danych, bo masz ją w tej samej linii co +HTTPREAD. Danych przeszukiwać chyba nie musisz?

    Pozdrawiam.
  • #16 20234195
    Karol966
    Poziom 31  
    Posty: 2041
    Pomógł: 83
    Ocena: 650
    Prawda, aczkolwiek to polecenie działa również poprawnie gdy prześlemy większą liczbę niż faktycznie została odebrana przez moduł gsm (np ostatnia ramka, ale jej wielkość również znam bo http get zwraca wielkość odebranego pliku). Może błąd leży gdzie indziej, sprawdzam czy odebrałem to czego oczekuję w ten sposób:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    a w RESPONSE_BUFFER mogą znaleźć się również znaki nie-ASCII

    Jako że to i tak rekomendowane to wprowadzam proste szyfrowanie pliku (xorowanie swoim kluczem dowolnej długości). Po dwóch dniach walki, zainstalowałem VS code, dodałem kilka dodatków + kompilator i z pomocą wujka google napisałem program, który szyfruje mi plik binarny. Właśnie wracam do pracy z bootloaderem.

    PS. Pomyślałem, że skoro nie mogę w prosty sposób zweryfikować CRC całego pliku to chcę dodatkowo do mojego programu szyfrującego dodać opcją dokładania sum kontrolnych każdej paczki (paczki wielkości SPM_PAGESIZE) a wówczas pobierał bym "AT+HTTPREAD=adres_początku, SPM_PAGESIZE+1"

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy różnic między plikami HEX a BIN, szczególnie w kontekście programowania układów AVR. Plik HEX, zgodny ze standardem Intel HEX, zawiera dane w formacie szesnastkowym oraz dodatkowe informacje, takie jak adresy i CRC, co pozwala na programowanie nieciągłych obszarów pamięci. Z kolei plik BIN to surowy zrzut pamięci, bajt po bajcie. Uczestnicy omawiają konwersję danych z formatu HEX do BIN, podkreślając, że dane w HEX są reprezentowane w ASCII, co wymaga konwersji do formatu binarnego przed zapisaniem do pamięci. Wskazano również na możliwość użycia funkcji strtol do konwersji szesnastkowej oraz na problemy związane z odbiorem danych przez UART, w tym konieczność szyfrowania i dodawania sum kontrolnych do przesyłanych paczek.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA