HOWTO: Link a binary file(s) into the application project using GNU build tools

Document created by stanish Employee on Mar 6, 2019Last modified by stanish Employee on Mar 15, 2019
Version 6Show Document
  • View in full screen mode

This document describes how to link a binary file(s) with an existing project in S32 Design Studio using GCC build tools.

 

Let's demonstrate this on S32K144 project in S32DS for ARM. Nevertheless it should work with any other GCC based development tools.

The first step is to add the binary file(s) into your project folder in the workspace.

In the example below I created two binary files "my_bin.bin" and "my_bin2.bin" and added them into a custom folder "bin_files".

I also entered 10 characters into each file.

 

my_bin.bin: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41  (represents 10 characters "A")

my_bin2.bin: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42  (represents 10 characters "B")

 

 

The next step is to modify linker configuration file (.ld) in order to specify the input file format and path to the binary files (see the line 14-17)

/* Specify the memory areas */
MEMORY
{
/* Flash */
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0
/* SRAM_L */
m_data (RW) : ORIGIN = 0x1FFF8000, LENGTH = 0x00008000
/* SRAM_U */
m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00007000
}

TARGET(binary) /* specify the file format of binary file */
INPUT (..\bin_files\my_bin.bin) /* first bin file path (relative to the output folder)*/
INPUT (..\bin_files\my_bin2.bin) /* second bin file path (relative to the output folder)*/
OUTPUT_FORMAT(default) /* restore the out file format */

/* Define output sections */
SECTIONS
{

...

 

Finally, in the SECTIONS block of .ld file specify where to place the binary files (in the example it is placed at the end of .text section - see the line 37,38).

/* Define output sections */
SECTIONS
{
/* The startup code goes first into internal flash */
.interrupts :
{
__VECTOR_TABLE = .;
__interrupts_start__ = .;
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
__interrupts_end__ = .;
. = ALIGN(4);
} > m_interrupts

.flash_config :
{
. = ALIGN(4);
KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */
. = ALIGN(4);
}> m_flash_config

/* The program code and other data goes into internal flash */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);

..\binary_files\my_bin.bin /* First binary file */
..\binary_files\my_bin2.bin /* Second binary file */

} > m_text

 

After successful compilation and linking let's check map and s-record file (HOWTO: Generate S-Record/Intel HEX/Binary file ) to confirm the binary files have been linked correctly:

 

 

.glue_7t 0x0000080c 0x0 linker stubs
*(.eh_frame)
*(.init)
*(.fini)
0x0000080c . = ALIGN (0x4)
..\bin_files\my_bin.bin()
.data 0x0000080c 0xa ..\bin_files\my_bin.bin
0x0000080c _binary____bin_files_my_bin_bin_start
0x00000816 _binary____bin_files_my_bin_bin_end
..\bin_files\my_bin2.bin()
.data 0x00000816 0xa ..\bin_files\my_bin2.bin
0x00000816 _binary____bin_files_my_bin2_bin_start
0x00000820 _binary____bin_files_my_bin2_bin_end

.vfp11_veneer 0x00000820 0x0
.vfp11_veneer 0x00000820 0x0 linker stubs

 

 

If you need to reference a binary file block start/end address in your code you can use the linker symbols generated automatically or you can define your own symbols in the linker script.

 

/* declare symbols from linker script file */
extern unsigned int _binary____bin_files_my_bin_bin_start;
extern unsigned int _binary____bin_files_my_bin_bin_end;


int main(void)
{
#define COUNTER_LIMIT 100

unsigned int counter = 0;

unsigned int * bin_start_ptr;
unsigned int * bin_end_ptr;

bin_start_ptr = &_binary____bin_files_my_bin_bin_start;
bin_end_ptr = &_binary____bin_files_my_bin_bin_end;


for(;;) {
counter++;
counter = *(bin_start_ptr); /*loads 0x4141_4141 into counter*/
if(counter > COUNTER_LIMIT) {
counter = 0;
}
}

return 0;
}

 

 

Note:

if it is intended to place the binary file at specific absolute address (e.g. if binary file that represent bootloader) you have to create a separate custom MEMORY and SECTION block in .ld file.

 

/* Specify the memory areas */
MEMORY
{
/* Flash */
m_bootloader (RX) : ORIGIN = 0x001000, LENGTH = 0x00010000 /* section for bootloadeer*/
m_text (RX) : ORIGIN = 0x00011000, LENGTH = 0x0040000 /*section for application code*/

...

}

TARGET(binary) /* specify the file format of binary file */
INPUT (..\bin_files\my_booloader.bin) /* bootloader bin file path (relative to the output folder)*/
OUTPUT_FORMAT(default) /* restore the out file format */

/* Define output sections */
SECTIONS
{

/* place the bootloader binary into 0x0..0x10000 */
.bootloader :
{
..\binary_files\my_bootloader.bin /* place the binary file here */

} > m_bootloader

...

 

 

Enjoy linking binaries in S32 Design Studio!

1 person found this helpful

Attachments

    Outcomes