The simple and toolchain-independent method is to generate a C code (or assembly) array from the binary data, then compile and link that to your code in the normal manner.
Writing your own tool to do that is trivial, but there are tools already that will do it for you. For example the SRecord tool suite includes this capability:
srec_cat mybinary.bin -binary -o mybinary.c -C-Array mybinary -INClude
will generate two files containing code of the form (elided example - your output will differ):
mybinary.c
/* http://srecord.sourceforge.net/ */
const unsigned char mybinary[] =
{
0xC0, 0x91, 0x00, 0x20, 0xA5, 0x01, 0x00, 0x08, 0xB1, 0x11, 0x00, 0x08,
...
0x31, 0x31, 0x30, 0x31, 0x30, 0x30, 0x2E, 0x30, 0x31, 0x2E, 0x30, 0x35,
0x2E, 0x30, 0x30, 0x00,
};
const unsigned long mybinary_termination = 0x00000185;
const unsigned long mybinary_start = 0x00000000;
const unsigned long mybinary_finish = 0x00004000;
const unsigned long mybinary_length = 0x00004000;
#define MYBINARY_TERMINATION 0x00000185
#define MYBINARY_START 0x00000000
#define MYBINARY_FINISH 0x00004000
#define MYBINARY_LENGTH 0x00004000
mybinary.h
#ifndef SRC_MYBINARY_H
#define SRC_MYBINARY_H
extern const unsigned long mybinary_termination;
extern const unsigned long mybinary_start;
extern const unsigned long mybinary_finish;
extern const unsigned long mybinary_length;
extern const unsigned char mybinary[];
#endif /* SRC_MYBINARY_H*/
The SRecord tools are complex and arcane but very powerful and can be used for all sorts of binary and object file conversion and manipulation. If you'd prefer something simpler that does just this one job then "binary to C code" is a suitable search term. Examples I have specifically used in the past:
They both generate code broadly similar to the above.
If you need to locate the binary at a specific location you will need to modify the generated code with your toolchain specific method. For example for IAR:
#pragma location=0x8020000
const unsigned char mybinary[] =
{...} ;
or
const unsigned char mybinary[] @ 0x8020000 =
{...} ;
Similarly you can locate the data in a user defined linker section - allowing the linker to determine where:
const unsigned char mybinary[] @ "BIN_SECTION" =
{...} ;
The syntax differs between across toolchains. I have not tried it but the SRecord -C-Array
filter has −POSTfix string
and −PREfix string
modifiers which can be used to add toolchain specific extensions in the generation (which is convenient if the binary will be modified frequently). However the IAR syntax is not well defined and all the examples are of the form:
<type> <symbol> @<location> = <initialiser> ;
so is "infix" not prefix or postfix. It may be that:
<type> <symbol> = <initialiser> @<location> ;
is valid, but the manual does not formally specify the syntax as far as I can tell, and I do not have the tool to test. If that does work then:
srec_cat mybinary.bin -binary -o mybinary.c -C-Array mybinary -INClude -POSTfix "@ 0x8020000"
const unsigned char mybinary[] =
{...} @ 0x8020000 ;
For linker-section location:
-POSTfix `@ "BIN_SECTION"`
If this syntax does not work you could write your own tool to modify the generated code and run both as a custom build step to automate, or use a text processing tool such as sed
to insert the location information. e.g.:
sed 's/mybinary\[\] =/mybinary\[\] @ 0x8020000 =/' mybinary.c
to replace char mybinary[] =
with char mybinary[] @ 0x8020000 =
in mybinary.c
Generally unless the data is to be accessed by some independently linked code code, or will be patched/updated independently of the code, it is unnecessary to locate the data at a specific location and you should let the linker locate it for portability between toolchains and runtime environments.