ARMLINK: Using Linker Scatter File for Buffer Management
Information in this knowledgebase article applies to:
How to use Arm linker scatter file for buffer managment?
To use ExecutionRegions in your scatter file to reserve memory for buffers which are referenced in your code, linker-defined symbols can be used. For a more advanced usage, the scatter file can be pre-processed with the ARMCC which allows using #define and importing header files for configuration. This technique is explained in this article.
Using a custom scatter file
µVision creates a scatter file using the information from the dialog Options for Target -> Target. The automatic creation of the scatter file can be enabled or disabled in the dialog Options for Target -> Linker with the option Use Memory Layout from Target dialog. When disabled, you can define a custom scatter file in the field Scatter File. By default, µVision suggests the scatter file that was generated in a previous build. Open the scatter file directly in µVision with the button Edit...
The scatter file
First, we take a look to the default scatter file created by µVision:
Add a new ExecutionRegion to define an empty buffer (refer to Syntax of an execution region description). For example:
The above line creates a buffer starting at [start_adr] with size of [size]. The attribute EMPTY reserves an empty memory block of a given size in the execution region. No section can be placed in a region with the attribute EMPTY. This is not a limitation, but protects this region from assignments.
Importing linker-defined symbols in your code
You can access the ExecutionRegion Buffer1 with the following code, which refers to the linker-defined symbol for this region:
The first line extern unsigned int Image$$Buffer1$$Base; imports the linker-defined symbol which refers the Base address of the ExecutionRegion. The second line, extern unsigned int Image$$Buffer1$$ZI$$Length; refers the to the length of the ExecutionRegion.
Because Image$$Buffer1$$Base and Image$$Buffer1$$ZI$$Length are symbols with an address, you need to use the "address (&)-operator" to get the value. For example:
Now, this symbol can be used with other commands. For example, with a memset command to initialize the buffer with a value:
Linker-defined symbols can be used directly without creating an object
Pre-process scatter files
The linker can invoke the ARMCC for pre-processing the scatter file. For this, add the following code to the first line of the scatter file:
The linker calls the ARMCC with the give parameter. The parameter -E intruct the compiler to execute only the pre-processor step.
When pre-processing the scatter file with ARMCC, you can use the directive #define as shown in the example below:
The #define statements can be put into a header (for example, config.h). If you are using #include statements in the scatter file to include header files, then you need to add -I and an include path. Otherwise ARMCC will not find the include file. Example of a header file config.h:
Now, the header file can be included in the scatter file
As you can see, in the first line, -I .\cfg has been added to the ARMCC command line. This is required because the config.h is placed in the .\cfg. Therefore, an include file path needs being set.
Please also see these Arm Community posts
Last Reviewed: Thursday, February 25, 2021
of your data.