8 votos

¿Cuál es la diferencia entre un archivo hexadecimal generado y un archivo binario en sistemas embebidos?

Tengo un proyecto STM32 (llamémoslo blinky). Este proyecto está desarrollado usando Keil IDE. Parpadea un LED cada 1 segundo. Cuando lo construyo, se genera un archivo HEX. Digamos que quiero actualizar la placa usando OAD (Over the Air Download). El nuevo código permite que el LED parpadee cada 2 segundos. Para poder flashearlo usando la OAD, debe haber un bootloader. Supongamos que este bootloader existe.

Mis preguntas son:

  • Para generar un archivo binario y actualizar la placa mediante OAD, ¿qué debo hacer exactamente en mi proyecto Keil?
  • ¿Debo exportar el proyecto como archivo binario en lugar de hexadecimal?
  • ¿Hay que hacer alguna otra configuración?

9voto

Existen MUCHOS formatos de archivo diferentes que representan exactamente el término "binario". Cuando se compila un archivo printf("¡Hola Mundo! \n "); programa en tu ordenador que es un binario, pero el binario contiene mucha más información que sólo las instrucciones y los datos del programa. Y dependiendo del sistema operativo se soportan múltiples formatos binarios diferentes. Si usas las herramientas gnu puedes ver desde arm-whatever-objcopy --help la lista de formatos de archivo soportados al final, en el mío

arm-none-eabi-objcopy: objetivos soportados: elf32-littlearm elf32-littlearm-fdpic elf32-bigarm elf32-bigarm-fdpic elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex

Si tomo un programa simple para su microcontrolador:

.thumb
.globl _start
_start:
    .word 0x20001000
    .word reset
reset: b reset

Y construirlo con las herramientas gnu (para fines de demostración tendrá sentido en un segundo)

arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -Ttext=0x08000000 so.o -o so.elf
arm-none-eabi-objdump -D so.elf
arm-none-eabi-objdump -D so.elf

so.elf:     file format elf32-littlearm

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000008    stmdaeq r0, {r3}

08000008 <reset>:
 8000008:   e7fe        b.n 8000008 <reset>

así que vemos que hay 10 bytes de código máquina. El formato del archivo se muestra como elf32-littlearm. Elf es un formato de archivo muy popular utilizado en varios lugares, ya que es bastante flexible y no está vinculado de ninguna manera a un sistema operativo ni a un objetivo.

En este caso el archivo elf tiene 66228 bytes de los cuales ahora sabemos que 10 son todo lo que necesitamos en la mcu para funcionar, el resto es información de depuración, estructura de archivos, etc.

hexdump -C so.elf
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 28 00 01 00 00 00  00 00 00 08 34 00 00 00  |..(.........4...|
00000020  c4 01 01 00 00 02 00 05  34 00 20 00 01 00 28 00  |........4. ...(.|
00000030  06 00 05 00 01 00 00 00  00 00 01 00 00 00 00 08  |................|
00000040  00 00 00 08 0a 00 00 00  0a 00 00 00 05 00 00 00  |................|
00000050  00 00 01 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00010000  00 10 00 20 08 00 00 08  fe e7 41 13 00 00 00 61  |... ......A....a|
00010010  65 61 62 69 00 01 09 00  00 00 06 02 09 01 00 00  |eabi............|
00010020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00010030  00 00 00 00 00 00 00 08  00 00 00 00 03 00 01 00  |................|
00010040  00 00 00 00 00 00 00 00  00 00 00 00 03 00 02 00  |................|
00010050  01 00 00 00 00 00 00 00  00 00 00 00 04 00 f1 ff  |................|
00010060  06 00 00 00 08 00 00 08  00 00 00 00 00 00 01 00  |................|
00010070  0c 00 00 00 00 00 00 08  00 00 00 00 00 00 01 00  |................|
00010080  0f 00 00 00 08 00 00 08  00 00 00 00 00 00 01 00  |................|
00010090  21 00 00 00 0a 00 01 08  00 00 00 00 10 00 01 00  |!...............|
000100a0  12 00 00 00 0a 00 01 08  00 00 00 00 10 00 01 00  |................|
000100b0  20 00 00 00 0a 00 01 08  00 00 00 00 10 00 01 00  | ...............|
000100c0  59 00 00 00 00 00 00 08  00 00 00 00 10 00 01 00  |Y...............|
000100d0  2c 00 00 00 0a 00 01 08  00 00 00 00 10 00 01 00  |,...............|
000100e0  38 00 00 00 0c 00 01 08  00 00 00 00 10 00 01 00  |8...............|
000100f0  40 00 00 00 0a 00 01 08  00 00 00 00 10 00 01 00  |@...............|
00010100  47 00 00 00 0c 00 01 08  00 00 00 00 10 00 01 00  |G...............|
00010110  4c 00 00 00 00 00 08 00  00 00 00 00 10 00 01 00  |L...............|
00010120  53 00 00 00 0a 00 01 08  00 00 00 00 10 00 01 00  |S...............|
00010130  00 73 6f 2e 6f 00 72 65  73 65 74 00 24 64 00 24  |.so.o.reset.$d.$|
00010140  74 00 5f 5f 62 73 73 5f  73 74 61 72 74 5f 5f 00  |t.__bss_start__.|
00010150  5f 5f 62 73 73 5f 65 6e  64 5f 5f 00 5f 5f 62 73  |__bss_end__.__bs|
00010160  73 5f 73 74 61 72 74 00  5f 5f 65 6e 64 5f 5f 00  |s_start.__end__.|
00010170  5f 65 64 61 74 61 00 5f  65 6e 64 00 5f 73 74 61  |_edata._end._sta|
00010180  63 6b 00 5f 5f 64 61 74  61 5f 73 74 61 72 74 00  |ck.__data_start.|
00010190  00 2e 73 79 6d 74 61 62  00 2e 73 74 72 74 61 62  |..symtab..strtab|
000101a0  00 2e 73 68 73 74 72 74  61 62 00 2e 74 65 78 74  |..shstrtab..text|
000101b0  00 2e 41 52 4d 2e 61 74  74 72 69 62 75 74 65 73  |..ARM.attributes|
000101c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000101e0  00 00 00 00 00 00 00 00  00 00 00 00 1b 00 00 00  |................|
000101f0  01 00 00 00 06 00 00 00  00 00 00 08 00 00 01 00  |................|
00010200  0a 00 00 00 00 00 00 00  00 00 00 00 04 00 00 00  |................|
00010210  00 00 00 00 21 00 00 00  03 00 00 70 00 00 00 00  |....!......p....|
00010220  00 00 00 00 0a 00 01 00  14 00 00 00 00 00 00 00  |................|
00010230  00 00 00 00 01 00 00 00  00 00 00 00 01 00 00 00  |................|
00010240  02 00 00 00 00 00 00 00  00 00 00 00 20 00 01 00  |............ ...|
00010250  10 01 00 00 04 00 00 00  07 00 00 00 04 00 00 00  |................|
00010260  10 00 00 00 09 00 00 00  03 00 00 00 00 00 00 00  |................|
00010270  00 00 00 00 30 01 01 00  60 00 00 00 00 00 00 00  |....0...`.......|
00010280  00 00 00 00 01 00 00 00  00 00 00 00 11 00 00 00  |................|
00010290  03 00 00 00 00 00 00 00  00 00 00 00 90 01 01 00  |................|
000102a0  31 00 00 00 00 00 00 00  00 00 00 00 01 00 00 00  |1...............|
000102b0  00 00 00 00                                       |....|
000102b4

Por lo general, cuando la gente dice archivo hexadecimal se refieren a intel hex, que se puede buscar el formato en wikipedia.

arm-none-eabi-objcopy so.elf -O ihex so.hex
cat so.hex
:020000040800F2
:0A0000000010002008000008FEE7D1
:0400000508000000EF
:00000001FF
hexdump -C so.hex
00000000  3a 30 32 30 30 30 30 30  34 30 38 30 30 46 32 0d  |:020000040800F2.|
00000010  0a 3a 30 41 30 30 30 30  30 30 30 30 31 30 30 30  |.:0A000000001000|
00000020  32 30 30 38 30 30 30 30  30 38 46 45 45 37 44 31  |2008000008FEE7D1|
00000030  0d 0a 3a 30 34 30 30 30  30 30 35 30 38 30 30 30  |..:0400000508000|
00000040  30 30 30 45 46 0d 0a 3a  30 30 30 30 30 30 30 31  |000EF..:00000001|
00000050  46 46 0d 0a                                       |FF..|
00000054

Se trata de un formato de archivo ASCII que contiene la información pertinente, la dirección en la que se almacenará la información y los propios bytes con una sobrecarga muy pequeña, en este caso de 84 bytes.

Mi preferencia es motorola s-record, yo era una persona de intel de vuelta en el día, pero como srecord porque es fácil de poner la dirección completa en la línea. Sí, esto no es casualidad estos formatos de archivo se remontan a los días en que Intel y Motorola eran los perros grandes y golpeando unos a otros y hacer las cosas específicamente para ser incompatibles, usted tiene un formato de archivo, vamos a tener un formato de archivo. se puede buscar srecord en wikipedia, así podría ser llamado srec o motorola srec o algo así.

arm-none-eabi-objcopy --srec-forceS3 so.elf -O srec so.srec
cat so.srec
S00A0000736F2E7372656338
S30F080000000010002008000008FEE7C3
S70508000000F2

también un archivo ASCII fácil de llevar alrededor y analizar al igual que ihex. se puede ver directamente la dirección 0x08000000 y la dirección 0x20001000, 0x08000008 (doh, lol, puse un error allí) y el código de máquina 0xe7fe. También se puede ver en el hexadecimal intel, sólo que la parte superior de la dirección 0x0800 está en una línea y el offset en otra (¿por qué necesitaríamos un programa de más de 64KBytes en un 8086?).

.thumb
.globl _start
_start:
    .word 0x20001000
    .word reset
.thumb_func
reset: b reset

error corregido

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   e7fe        b.n 8000008 <reset>

Hasta ahora, estos tres formatos de archivo se llaman binarios de la misma manera que tu archivo hello_world.exe se llama binario. Contienen la información "binaria" en este caso una tabla de vectores y algo de código máquina, también contienen el lugar donde quiero cargar la información del programa. Que para este programa no es realmente tan interesante, pero para los programas donde digamos que tengo algo de .text que quiere aterrizar en 0x00000 y algo de .data que quiere aterrizar en 0x10000000 digamos 1 byte en 0x00000000 y 1 byte en 0x10000000 realmente solo necesito dos direcciones y dos bytes en un formato de archivo para almacenar esa informacion.

.text
.byte 0x11
.data
.byte 0x22

arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -Ttext=0x00000000 -Tdata=0x10000000 so.o -o so.elf
arm-none-eabi-objcopy --srec-forceS3 so.elf -O srec so.srec
cat so.srec 
S00A0000736F2E7372656338
S3060000000011E8
S3061000000022C7
S70500000000FA

ahora viene el problema, algunas personas (la mayoría de nosotros) reutilizan el término binario para referirse a una imagen de memoria byte por byte, en este caso en lugar de un archivo s-record de 78 bytes se necesitaría un 0x10000001 o 268.435.457 bytes. Para mantener ese archivo con la mayoría de los bytes de relleno para que el 0x22 aterrice en el lugar correcto en relación con el 0x11.

Con nuestro programa original de arriba.

arm-none-eabi-objcopy so.elf -O binary so.bin
hexdump -C so.bin
00000000  00 10 00 20 09 00 00 08  fe e7                    |... ......|
0000000a

es un archivo de 12 bytes, sólo el byte que necesitamos y sigue siendo confuso, ya que no es un archivo de 0x08000000+12 bytes para ser alineados en la dirección cero, pero el usuario de este archivo tiene que saber que tiene que aterrizar en el espacio de memoria stm32 en 0x08000000 que aunque tenemos esos valores o cerca de ellos en el archivo no hay estructura de archivo que nos permite saber que sólo hay que recordar y no meter la pata.

Así que después de todo lo que TL;DR, el punto es el término binario viene en muchas formas, en cuanto al tipo de sistema embebido que está hablando (en este punto en el tiempo del sistema embebido es un concepto tan amplio y nuestros teléfonos son básicamente los sistemas embebidos en el microcontrolador que está hablando es un sistema mucho más pequeño con más restricciones y reglas) se trata de las herramientas que está utilizando para colocar el archivo en la memoria flash. La familia stm32 en particular está soportada por una amplia gama de herramientas, de las cuales Kiel es una parte muy pequeña. Kiel tiene formatos de archivo que soporta, puedes buscarlos, algunas herramientas sólo soportan el tipo de imagen de memoria binaria, aunque me parece una tontería, algunos soportan los más simples como intel hex y/o motorola srecord y que ha sido una norma durante décadas. En estos días si sólo soporta uno sería más probable elf y que estaría bien para el 99,9% con un montón de nueves después de que de nosotros. El estilo de imagen de memoria tiene algún sentido cuando se trata de lo que se convirtió en un enfoque de tipo mbed las placas nucleo de st se muestran como una unidad virtual usb/thumb en su computadora y usted arrastra y suelta el archivo en eso, el bootloader mcu se detiene y carga la flash de la mcu de destino. pero cuando se utiliza un depurador como openocd o algo así en una interfaz gráfica que desea algo más que la imagen de memoria por varias razones. por lo que el elf o cualquiera que sea el formato de archivo nativo del compilador que se utiliza a menudo en frente de esa herramienta tiene sentido.

Para tu pregunta concreta, tienes que leer la documentación de tu herramienta o simplemente hacer algunos experimentos para averiguar los formatos de archivo compatibles.

Me sorprendería que Kiel sólo produjera o enviara archivos en formato hexadecimal Intel, quizás lo llamen .hex pero no es un hexadecimal Intel. Si lo examina con un editor de texto ¿se parece a los archivos hexadecimales intel arriba?

Si lo es puedes usar las herramientas gnu binutils con ese archivo hexadecimal kiel para por ejemplo hacer un archivo tipo imagen de memoria:

arm-none-eabi-objcopy -I ihex so.hex -O binary so.bin
hexdump -C so.bin
00000000  00 10 00 20 09 00 00 08  fe e7                    |... ......|
0000000a

pero debido a que mucha información aparte de la mínima para cargar bytes en alguna dirección se pierde en el archivo de formato hexadecimal intel no se puede convertir de nuevo a un elf mayormente utilizable u otros formatos similares. Esta es la razón por la que las herramientas suelen utilizar formatos de archivo ricos en funciones como elf, a partir del cual se puede trabajar directamente o convertir a un formato que retenga menos información.

3voto

Matt Puntos 150

Un archivo hexadecimal (formato Intel .Hex) es un archivo de texto que contiene una colección de registros, cada uno de los cuales contiene una dirección y algunos datos. Ese archivo se convierte, sobre la marcha, en datos binarios y se escribe en la memoria flash. A veces también se realiza una validación, es decir, no se pueden escribir datos en una dirección no válida.

Un archivo binario son los datos en bruto, que suelen empezar en la dirección 0. No existe ningún proceso de conversión o validación.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X