Dzisiaj również tematyka nieco techniczno-niszowa i tym razem bez wstępnej dygresji :).
Z formatem Intel Hex pewnie stosunkowo niewielu programistów się spotkało i być może niewielu się spotka. Nie mniej jednak, gdy pojawia się taka konieczność – nie jest tak łatwo zdobyć proste i „zjadliwe” informacje a jeszcze trudniej gotową do zaadaptowania implementację w danej technologii.
Zmierzyłem się z tym problemem kilka miesięcy temu i ostatecznie konwerter do tego formatu napisałem sam. W tym poście podzielę się czym to jeść. Na końcu posta znajdziesz link do repozytorium na github, gdzie wrzuciłem prosty przykładowy konwerter napisany w C#.
Format Intel Hex dotyczy plików tekstowych w kodowaniu ASCII. Każda linia w takim pliku zawiera jeden rekord „Hex”. Rekordy te zawierają kod maszynowy w formacie hexadecymalnym (szasnastkowym) oraz pewne informacje stałe (opcjonalnie). Pliki w formacie Intel Hex są często używane do transferowania programu lub danych, które są następnie zapisywane w ROM-ie lub EPROM-ie urządzeń. Większość programatorów EEPROM lub emulatorów urządzeń potrafi korzystać z plików w formacie Intel Hex. Mówimy więc o tematyce niejako związanej z programowaniem układów mikroprocesorowych – chociaż nie do końca. W tym formacie przesyłane są również np. grafiki wyświetlane na prostych wyświetlaczach lub grafiki na etykiety drukowane przez drukarki kodów kreskowych.
Właśnie w tym ostatnim kontekście przeanalizujemy ten format. Przykładowy konwerter, który wrzuciłem do repozytorium służy właśnie do konwertowania plików .bmp do formatu Intel Hex rozumianego przez drukarki kodów kreskowych Intermec.
Istotną kwestią jest pewna dowolność producentów urządzeń w podejściu do formatu. Często można spotkać się z pewnymi dodatkowymi wymaganiami jeżeli chodzi o nagłówek i stopkę transferowanego pliku. Tak jest właśnie w przypadku drukarek Intermec i ten nagłowek i stopkę również można znaleźć w moim przykładowym kodzie.
Rekord w formacie IntelHex ma następującą budowę:
-
Każda linia (czyli każdy rekord) zaczyna się znakiem dwukropka :
-
Następnie znajduje się informacja o długości (ilości) danych zawartych w rekordzie
-
Następnie adres, który mówi o pozycji w rekordzie. Jest to bardzo ważne pole, ponieważ pozwala na poprawne uporządkowanie sekwencji rekordów
-
Typ rekordu – i tutaj znajdziemy:
-
Dane właściwe
-
Suma kontrolna
Na końcu rekordu, w zależności od wymagań urządzenia interpretującego musi znaleźć się znak końca linii (CR – czyli \r w C#) a czasami również i przejścia do nowej linii (LF – czyli \n w C#).
Sumę kontrolną liczymy w dość standardowy sposób. Zsumowane bajty odejmujemy zsumowaną wartości 255. Sumę oczywiście musimy zapisać w formacie hexadecymalnym.
Jeżeli chodzi o mój przykład kodu, służy on do konwertowania obrazów (bitmap) monochromatycznych o wymiarach od 16×16 do 32×32 piksele do formatu rozumianego przez drukarki kodów kreskowych Intermec. Taka bitmapa jest następnie konwertowana do postaci tablicy bajtów i kolejne wiersze konwertowane są według opisanej powyżej metody.
Kod nie jest zbyt uniwersalny, ale myślę że daje dobry pogląd na to w jaki sposób zmierzyć się z tematem.
Adres repozytorium z przykładowym kodem: