Перейти к содержанию
    

Парсер hex файла

Решил доделать свой bootloader что бы он принимал прошивку в hex формате. Сам формат оказался достаточно простым, но при реализации  столкнулся с некоторыми вопросами.

Процессор у меня stm32f103, там размер страницы 1-2 Кбайт, по этому(для варианта записи bin файла) я сначала накапливал данные на запись по размеру страницы, а потом стирал страницу и записывал новые данные. Аналогично думаю сделать и для Hex файла.

Получается такой алгоритм:

  1. Принять блок HEX данных 512 байт
  2. Конвертировать блок, скопировать в накапливающий буфер(или сразу туда конвертировать)
  3. Дождаться заполнения всего записывающего буфера.
  4. Записать буфер в Flash.

Основная проблема с которой я столкнулся, это  ситуация когда строка hex файла разбилась на два разных блока.

Пока подумываю сделать проверку каждой строки на завершающие символы "\r\n", и если их не было значит данную строку надо скопировать, и как-то склеить со следующим буфером. Склеивать функцией strcat, как-то не очень нравиться 512 байт копировать =(. Как такое сделать правильнее ? 

Второй вопрос могут ли адреса смежных строк hex файл сильно отличаться (с одним типом '00' Data Record )? Полистав несколько hex файлов такого не заметил. 

Изменено пользователем pokk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, pokk сказал:

Как такое сделать правильнее ? 

hex - это строковый тип данных. А значит, как у многих строковых типов, минимальная единица данных у него - строка. А значит и принимать и обрабатывать его нужно построчно. А не как у вас.

 

4 часа назад, pokk сказал:

Второй вопрос могут ли адреса смежных строк hex файл сильно отличаться (с одним типом '00' Data Record )? Полистав несколько hex файлов такого не заметил. 

Ещё раз: в hex каждая строка - независима. Со своим адресом, контрольной суммой и содержимым. И в общем случае не имеет никакой связи с другой строкой. Читайте описание формата hex - неужто в гугле забанили??

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

42 minutes ago, Edit2007 said:

Лучше перед передачей данных в МК сделать преобразование HEX->BIN.

В таком варианте передаться много не нужных данных, в последнем секторе находятся настройки ПО, по этому до них заполняется все 0xFF и находиться в BIN файле.  

36 minutes ago, jcxz said:

А значит и принимать и обрабатывать его нужно построчно. А не как у вас. 

Увы передача идет по TFTP, оттуда и блоки по 512.

44 minutes ago, jcxz said:

Ещё раз: в hex каждая строка - независима. Со своим адресом, контрольной суммой и содержимым.

Т.е её надо сразу записать во Flash, иначе не как? Как тогда определять был ли стерт сектор или нет,после записи пару строк?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, pokk сказал:

Увы передача идет по TFTP, оттуда и блоки по 512.

И что? В чём проблема? Да хоть смс-ками по N байт - какая разница?

Цитата

Т.е её надо сразу записать во Flash, иначе не как? Как тогда определять был ли стерт сектор или нет,после записи пару строк?

Зачем её писать во флешь??? :wacko2:

hex-файл надо принимать в виде потока символов, разбивать на лету этот поток символов на отдельные строки и эти строки уже обрабатывать. Напишите элементарную функцию, которая на входе принимает один символ и подавайте туда этот поток символ-за-символом. А внутри функция выполняет всю работу по разбору строки (обнаружению границ строки и т.д.). Когда строка полностью разобрана и проверена и получен её адрес - тогда уже её содержимое может куда-то записываться (во флешь).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 минут назад, pokk сказал:

В таком варианте передаться много не нужных данных, в последнем секторе находятся настройки ПО, по этому до них заполняется все 0xFF и находиться в BIN файле.

Можно и так. Только опять - с умом:

На стороне передатчика программа читает hex-файл, парсит его на строки, содержимое каждой строки (адрес+данные+контрольная_сумма+etc.) записывает в двоичном виде в виде одного кадра. И далее этот кадр отправляется в целевое устройство любым подходящим кадр-ориентированным протоколом обмена (SLIP, COBS, Modbus, ...). Траффик конечно будет меньше. Нужно-ли это - решать Вам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 minutes ago, jcxz said:

тогда уже её содержимое может куда-то записываться (во флешь). 

Я про это и имел ввиду что,  во flash писать данными по 16 байтами, по адресу из вытащенному из данной строки, но как узнать что сектор по текущему адресу был стерт и его не надо повторно стрирать ?

22 minutes ago, jcxz said:

hex-файл надо принимать в виде потока символов

Я работаю через wiznet 5500, он принимает IP пакет, а из нечего по SPI я считываю сами данные UDP пакета, с помощью DMA.

Ну дальше этот кусок разбираю посимвольно.

 

16 minutes ago, jcxz said:

Траффик конечно будет меньше. Нужно-ли это - решать Вам. 

Не в трафике дело, а в том что бы не перетирать, пустые страницы, тем самым быстрее файл запишется.

Ну и проверка CRС на лету, при не валидности CRC строки, можно повторно запросить строку/блок.

 

Изменено пользователем pokk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, pokk сказал:

Я про это и имел ввиду что,  во flash писать данными по 16 байтами, по адресу из вытащенному из данной строки, но как узнать что сектор по текущему адресу был стерт и его не надо повторно стрирать ?

Прочитать это место - разве трудно? И проверить что все биты могут быть запрограммированы.

4 минуты назад, pokk сказал:

Я работаю через wiznet 5500, он принимает IP пакет, а из нечего по SPI я считываю сами данные UDP пакета, с помощью DMA.

Ну дальше этот кусок разбираю посимвольно.

Если Вы работаете через UDP, то кроме этого надо ещё проанализировать, что UDP-кадр не был дублем какого-то предыдущего. И что не перепутан порядок следования UDP-кадров. Так как UDP не даёт гарантии целостности и порядка следования кадров данных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 minutes ago, jcxz said:

И проверить что все биты могут быть запрограммированы.

О проверить на 0xFF, да можно, я просто всегда очищал при переходе от одного сектора к другому. Благодарю, я чуть не наворотил массив содержащий номера стертых секторов =).

11 minutes ago, jcxz said:

И что не перепутан порядок следования UDP-кадров

Это реализовано в протоколе TFTP, там к блоку данных крепиться шапка в которой указанно номер пакета с данными, а в ответ отправляешь номер следующего пакета данных, который надо принять.

 

Но вопрос, на соединение строки hex из разных блоков все ещё остался =(.

 

Изменено пользователем pokk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 минут назад, pokk сказал:

О проверить на 0xFF, да можно, я просто всегда очищал при переходе от одного сектора к другому. Благодарю, я чуть не наворотил массив содержащий номера стертых секторов =).

Тут надо не номера стёртых хранить, а адреса принятых сегментов. Например: пришёл кадр-X1 который пишется внутрь сектора-Y. Вы проверили: всё ОК - он нормально может быть записан в этот сектор, так как любой бит может быть запрограммирован или оставлен без изменения (т.е. - нет битов, которые нужно перевести из '0' в '1' (что можно сделать только стиранием)). Записываете этот сектор. Но в других адресах этого сектора есть места содержащие '0' (так как сектор не стирался). А затем приходит следующий кадр-X2, который как раз требует записи в те грязные '0' битов со значением =='1'. А значит - нужно стереть сектор-Y, и только потом писать туда этот новый кадр-X2. Но чтобы не потерять ранее записанные данные из кадра-X1, нужно сперва считать всё ранее записанное содержимое сектора, стереть его, записать старое содержимое (но только полезную его часть, ранее переданную), а потом  записать содержимое кадра-X2.

Так что:

1) Или хранить карту ранее записанных данных. Карту байт. Так как адрес и размер hex-строки может иметь произвольное байтовое смещение (в общем случае).

2) Или хранить карту стираний секторов. И стирать сектор не в тот момент, когда невозможно в него записать данные из нового кадра, а в тот момент когда принят первый кадр попадающий в этот сектор. Вне зависимости от содержимого сектора. Т.е. - при первом попадании - стирать, при последующих - не стирать.

Первый вариант требует больше памяти, но можно получить меньше стираний секторов.

 

Цитата

Это реализовано в протоколе TFTP, там к блоку данных крепиться шапка в которой указанно номер пакета с данными, а в ответ отправляешь номер следующего пакета данных, который надо принять.

Ну если каждый такой блок передаётся одним UDP-кадром (а не режется на несколько UDP-кадров) - тогда нет проблем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, jcxz said:

Первый вариант требует больше памяти, но можно получить меньше стираний секторов.

Из за чего меньше стираний секторов? Из за того что они изначально могут быть стертыми (при увеличени прошивки)?

А по поводу склейки строки hex из разных блоков, что можете посоветовать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, pokk сказал:

Из за чего меньше стираний секторов? Из за того что они изначально могут быть стертыми (при увеличени прошивки)?

Из-за того что для записи новых данных может не требоваться стирание сектора. См. выше - я же описал алгоритм.

Цитата

А по поводу склейки строки hex из разных блоков, что можете посоветовать?

Я же уже посоветовал! Вы читаете? Не надо ничего склеивать. Надо весь hex-файл обрабатывать как поток символов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, pokk сказал:

таком варианте передаться много не нужных данных, в последнем секторе находятся настройки ПО, по этому до них заполняется все 0xFF и находиться в BIN файле.

И в чем тут проблема, простейший упаковщик повторяющихся данных решит эту задачу гораздо проще и удобнее, чем реалтайм парсер хекса в условиях ограниченного ОЗУ под буфер.

И кстати, про настройки ПО - в курсе, что флеш - это не ЕЕПРОМ, у него кол-во циклов перезаписи много ниже?

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Цитата

Лучше перед передачей данных в МК сделать преобразование HEX->BIN.

Цитата

В таком варианте передаться много не нужных данных, в последнем секторе находятся настройки ПО, по этому до них заполняется все 0xFF и находиться в BIN файле.  

Наверное меня не так поняли. Вы из строкового HEX-файла поучаете бинарный образ прошивки. Далее этот образ разбиваете по страницам (секторам) и передаете в МК для записи. Все упрощается на порядок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...