I present a function below to allow this:
hex2bin path/to/myfirmware1.hex
hex2bin path/to/myfirmware1.hex path/to/myfirmware2.hex
hex2bin myfirmware1.hex myfirmware2.hex myfirmware3.hex myfirmware4.hex
# etc.
Note: get the latest versions of my hex2bin
and hex2xxdhex
functions in my eRCaGuy_dotfiles repo here: .bash_useful_functions.
Bash function to mass-convert Intel *.hex
firmware files to *.bin
firmware files, and to *.xxd.hex
files for comparison in meld
To add onto @A. Genchev's answer: I find it tedious to have to have such a long command when I want to convert many hex files at once, so I wrote this helper function.
Copy and paste this into the bottom of your ~/.bashrc
file, then run . ~/.bashrc
to re-source your ~/.basrhc
file and make this function available to you:
# Function to convert .hex firmware files to .bin
#
# Example usage:
#
# # this produces "path/to/myfile.bin" from "path/to/myfile.hex"
# hex2bin path/to/myfile.hex
#
# # you can pass multiple paths at once too
# hex2bin path/to/myfile1.hex path/to/myfile2.hex path/to/myfile3.hex
#
hex2bin() {
# treat all input args as file paths
for filepath_hex in "$@"; do
# See: https://stackoverflow.com/a/965072/4561887
filepath_hex_no_extension="${filepath_hex%.*}"
filepath_bin="${filepath_hex_no_extension}.bin"
# debugging
# echo "filepath_hex_no_extension = $filepath_hex_no_extension"
# echo "filepath_bin = $filepath_bin"
echo "Converting \"$filepath_hex\" to \"$filepath_bin\"."
objcopy --input-target=ihex --output-target=binary \
"$filepath_hex" "$filepath_bin"
done
}
# (Optional) add an alias prefixed with your initials so you can find all your
# custom aliases and functions easily by typing your initials followed by an
# underscore and hitting Tab Tab.
alias gs_hex2bin="hex2bin"
If you have a different toolchain, just replace objcopy
with the version of objcopy
from your toolchain. Ex: for the Microchip MPLAB XC32 compiler toolchain for PIC microcontrollers, use xc32-objcopy
instead of objcopy
.
Now, instead of this:
objcopy --input-target=ihex --output-target=binary \
path/to/myfirmware1.hex path/to/myfirmware1.bin
objcopy --input-target=ihex --output-target=binary \
path/to/myfirmware2.hex path/to/myfirmware2.bin
...you can do this:
hex2bin path/to/myfirmware1.hex path/to/myfirmware2.hex
You can pass in as many pathnames as you want all at once.
Going further: comparing and analyzing hex/binary file differences using objcopy
, xxd
, and meld
What if you want to compare two Intel hex firmware files to look for differences? Perhaps two hex firmware images are nearly identical, but differ only in some strings, IP addresses, or timestamps stored inside of them. That would be nice to know.
Here's how:
# - for "path/to/myfirmware1.hex", produce both "path/to/myfirmware1.bin"
# and "path/to/myfirmware1.xxd.hex"
# - for "path/to/myfirmware2.hex", produce both "path/to/myfirmware2.bin"
# and "path/to/myfirmware2.xxd.hex"
hex2xxdhex "path/to/myfirmware1.hex" "path/to/myfirmware2.hex"
# now compare the two `.xxd.hex` output files in `meld`
meld "path/to/myfirmware1.xxd.hex" "path/to/myfirmware2.xxd.hex"
Example output in meld
:


Here is the definition of my hex2xxdhex
function:
# Function to convert .hex firmware files to .bin and then to a
# human-compare-friendly .xxd.hex, so you can easily compare two files with
# `diff` or `meld`.
# - See my answer here: https://superuser.com/a/1790518/425838
#
# Example usage:
#
# # this produces both "path/to/myfile.bin" and "path/to/myfile.xxd.hex"
# # from "path/to/myfile.hex"
# hex2xxdhex path/to/myfile.hex
#
# # you can pass multiple paths at once too
# hex2xxdhex path/to/myfile1.hex path/to/myfile2.hex
# # then compare the two output ".xxd.hex" files with `meld`
# meld path/to/myfile1.xxd.hex path/to/myfile2.xxd.hex
#
hex2xxdhex() {
# treat all input args as file paths
for filepath_hex in "$@"; do
# See: https://stackoverflow.com/a/965072/4561887
filepath_hex_no_extension="${filepath_hex%.*}"
filepath_bin="${filepath_hex_no_extension}.bin"
filepath_xxdhex="${filepath_hex_no_extension}.xxd.hex"
echo "Converting \"$filepath_hex\" to \"$filepath_bin\" and to"\
"\"$filepath_xxdhex\"."
objcopy --input-target=ihex --output-target=binary \
"$filepath_hex" "$filepath_bin"
xxd "$filepath_bin" "$filepath_xxdhex"
done
}
alias gs_hex2xxdhex="hex2xxdhex"
For a lot more detail, see my answer here: Super User: How to compare binary files, hex files, and Intel hex firmware files with meld