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.