Преобразовываются ли шестнадцатеричные файлы Intel в двоичный формат перед записью на флэш-память Atmega?

Я просматривал некоторые ресурсы о загрузчиках, программистах и т. д. (я новичок в этой конкретной теме) и о том, как они работают с чипами Atmega и программированием плат Arduino. Мое исследование, возможно, было поверхностным, но ни в одной из онлайн-статей/блогов/сообщений на форумах, которые я просматривал, не упоминалось, что файл .hex (в формате Intel Hex ASCII) необходимо конвертировать в любой другой двоичный формат. Хотя мне показалось странным, что можно напрямую записывать простой текст ASCII во флэш-память MCU. Кроме того, при использовании AVR Burn-o-Mat (интерфейс GUI для avrdude) я пару раз замечал, что количество записываемых байтов было значительно меньше фактического размера шестнадцатеричного файла. Совсем недавно я просмотрел эту библиотеку на github, которая преобразует шестнадцатеричный формат Intel в двоичный формат. Прав ли я, говоря, что шестнадцатеричный файл необходимо преобразовать в двоичный? Так, например, делает ли avrdude это перед отправкой двоичного потока в загрузчик (при загрузке скетча через IDE)?

, 👍4

Обсуждение

Я использую эту библиотеку в скетче, который считывает шестнадцатеричный код с SD-карты и записывает его в двоичном виде для прошивки на Arduino Mega. https://github.com/JAndrassy/ArduinoOTA/blob/master/examples/Advanced/SD2Flash2BootAVRHex/SD2Flash2BootAVRHex.ino, @Juraj

Если вы прочитаете документацию Avrdude, вы обнаружите, что она может использовать для прошивки различные форматы двоичных файлов, включая двоичные. Аргумент командной строки включает спецификатор., @the busybee


1 ответ


4

Да, шестнадцатеричные коды в файле .hex считываются avrdude (или другими программами) и записываются в MCU в двоичном виде. Небольшой микропроцессор не сможет читать команды формата ASCII.

См. мой ответ на тему Что происходит, когда код загружается с помощью загрузчика?


(В продолжение некоторых комментариев)

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

Я думаю, что здесь есть некоторая путаница из-за разных способов представления или хранения чисел. Например, число, которое мы знаем как «двадцать»; может быть записано (в файле) как:

  • 20 (десятичное число)
  • 00020 (десятичное число с ведущими нулями)
  • 0014 (шестнадцатеричный)
  • 0024 (восьмеричное число)
  • 10100 (двоичные цифры)

Теперь такая программа, как Avrdude, может читать числа в любом из этих форматов, внутренне конвертировать их в «двоичный» формат. и отправить один байт, являющийся этим двоичным числом, в MCU для помещения в байт памяти программы.

В формате .hex, который система Arduino создает в процессе компиляции, используются строки следующего формата:

Line format:
  :nnaaaatt(data)ss
  Where:
  :      = a colon
  (All of below in hex format)
  nn     = length of data part
  aaaa   = address (eg. where to write data)
  tt     = transaction type
           00 = data
           01 = end of file
           02 = extended segment address (changes high-order byte of the address)
           03 = start segment address *
           04 = linear address *
           05 = start linear address *
  (data) = variable length data
  ss     = sumcheck
            * We don't use these

Вышеизложенное из комментариев в моем файле https://github.com/nickgammon/arduino_sketches/ blob/master/Atmega_Hex_Uploader/File_Utils.ino

Пример: Optiboot во всей красе (всего 512 байт):

:107E0000112484B714BE81FFF0D085E080938100F7
:107E100082E08093C00088E18093C10086E0809377
:107E2000C20080E18093C4008EE0C9D0259A86E02C
:107E300020E33CEF91E0309385002093840096BBD3
:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
:107E6000A2D0813461F49FD0082FAFD0023811F036
:107E7000013811F484E001C083E08DD089C08234E0
:107E800011F484E103C0853419F485E0A6D080C0E4
:107E9000853579F488D0E82EFF2485D0082F10E0AE
:107EA000102F00270E291F29000F111F8ED06801E7
:107EB0006FC0863521F484E090D080E0DECF843638
:107EC00009F040C070D06FD0082F6DD080E0C81688
:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
:107F0000A601A0E0B1E02C9130E011968C91119780
:107F100090E0982F8827822B932B1296FA010C0160
:107F200087BEE89511244E5F5F4FF1E0A038BF0790
:107F300051F7F601A7BEE89507B600FCFDCF97BE46
:107F4000E89526C08437B1F42ED02DD0F82E2BD052
:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
:107F7000D11C0EC0853739F428D08EE10CD085E9AC
:107F80000AD08FE07ACF813511F488E018D01DD067
:107F900080E101D065CF982F8091C00085FFFCCF94
:107FA0009093C60008958091C00087FFFCCF809118
:107FB000C00084FD01C0A8958091C6000895E0E648
:107FC000F0E098E1908380830895EDDF803219F02E
:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
:047FF000FF270994CA
:027FFE00040479
:0400000300007E007B
:00000001FF

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

Самое первое, что мы можем сделать из этого, это то, что размер файла будет более чем вдвое превышать объем запрограммированной памяти. Например, чтобы запрограммировать "AB" в шестнадцатеричном формате для этого потребуется два байта в файле .hex ("A", за которым следует "B"), но они будут преобразованы в эквивалентный однобайтовый "двоичный" код . номер, который окажется в памяти MCU.

Тогда из-за двоеточия, типа транзакции, длины строки и проверки суммы файл будет еще несколько длиннее, чем удвоенное количество байтов, которые нужно запрограммировать в MCU. Это накладные расходы на макет файла.

,

«_[...] не сможет [...]_» неверно как общее утверждение. Авторы загрузчика сознательно решили использовать только двоичные данные. ;-) Вы также можете добавить, что Avrdude может считывать на флэш-память двоичные файлы нескольких форматов, включая двоичные., @the busybee

Я написал это в контексте вопроса: «*Мне показалось странным, что можно было бы напрямую записать простой текст ASCII во флэш-память микроконтроллера * - текстовый файл ASCII не записывается во флэш-память, а затем выполняется. Конечно, микропроцессор мог читать текст ASCII и интерпретировать его под управлением программы, но сам текст ASCII не загружается во флэш-память и не выполняется., @Nick Gammon

Я вижу, так это формулировка "читать". Вы имеете в виду «читать для выполнения», а я понял «читать для программирования флэша». Поскольку таких, как я, может быть больше, не могли бы вы расширить ответ? -- Поскольку хранить программы в шестнадцатеричном формате ASCII было бы пустой тратой места, я об этом не подумал., @the busybee

Я попытался объяснить это лучше., @Nick Gammon

:-D Вау. Да, объяснять Intelhex — это здорово, и это хорошо в контексте. -- Пожалуйста, не поймите неправильно, моя скромная проблема касается только слова «читать» во втором предложении, и ее можно удовлетворительно прояснить с помощью содержания вашего первого комментария., @the busybee

«*Потому что хранить программы в шестнадцатеричном коде ASCII было бы пустой тратой места*» — использование проверок сумм помогает убедиться, что данные были прочитаны правильно, поэтому это не пустая трата места., @Nick Gammon

Кроме того, использование адресных байтов означает, что шестнадцатеричный файл может быть более компактным. Это означает, что вы можете записать 100 байт *здесь*, а затем 50 байт *туда* без необходимости дополнять разницу тысячами нулей., @Nick Gammon

Это все правильно, и поэтому такие форматы, как Intelhex, имеют свою долю и преимущества. В любом случае, мы говорили о хранении программы на кристалле. И поскольку сохранение машинного кода для выполнения в Intelhex сильно усложняет ситуацию, я понятия не имел, что вы это имели в виду., @the busybee