Placing a group of functions or variables in a specific section

Technical Note 27498

Targets:
ARM

Component:
Linker

Updated:
10/3/2017 1:15 PM

Introduction

This technical note describes two methods for placing multiple functions or variables in a specified section, without using several #pragma location directives.

Discussion

One function (or variable) can be placed in a named section using #pragma location, for example:

#pragma location="MY_FUNC"
void f(void);

However, using #pragma location becomes impractical when there are many functions (or variables) to place.

These methods will be described:

•    Placing several functions/variables using a single pragma directive.
•    Placing several functions from an object file using a linker placement directive.

Placing several functions/variables using a single pragma directive

There are two available pragma directives for setting default placement and attributes for declarations and definitions of functions/variables:

•    #pragma default_variable_attributes
•    #pragma default_function_attributes

These two pragma directives make it possible to use a single #pragma for multiple declarations and definitions, instead of using several #pragma location directives.

An example of how to use these pragma directives

In your source code place some functions in the section MY_FUNC.

#pragma default_function_attributes = @ "MY_FUNC"

int fun1(int x)
{
    return x + 1;
}

int fun2(int x)
{
    return x - 1;
}

/* Stop placing functions in section MY_FUNC */
#pragma default_function_attributes =

int fun3(int x)
{
    return x + x;
}

/* Place following data in section MY_DATA */
#pragma default_variable_attributes = @ "MY_DATA"

int data1;
int data2;

/* Stop placing data in section MY_DATA */
#pragma default_variable_attributes =

int data3;

int main()
{
    data1 = fun1(5);
    data2 = fun2(5);
    data3 = fun3(5);

    return data1 + data2 + data3;
}

Add the following lines to your linker configuration file (icf) to place all data in a specified memory address range in the section MY_DATA:

define region DATA_region = mem:[from 0x20000000 to 0x20001FFF ];
place in DATA_region { readwrite section MY_DATA };

Add the following lines to your linker configuration file (icf) to place all code in a specified memory address range in the section MY_DATA:

define region FUNC_region = mem:[ from 0x70000 to 0x70FFF ];
place in FUNC_region { readonly section MY_FUNC };

Placing several functions from an object file using a linker placement directive

A more convenient method than using several #pragma location is to put the functions in a separate source file, and let the linker select all functions from the object file using a place in directive.

Follow these steps:

1.    Collect the functions in one (or more) source files.
2.    Remove any #pragma location you have used earlier.
3.    Edit the .icf file, and add a place in directive that contains the keyword object as exemplified below.

Add the following lines to your .icf file to place all code from the source file Utilities.c in a specified memory address range:

define region UTILITIES_region = mem:[ from 0x71000 to 0x71FFF ];
place in UTILITIES_region { readonly object Utilities.o };

Conclusion

You do not need to use several #pragma location directives to place data/code in a specified memory address range. Instead you can use the described methods.

For more information about the linker placement directive, see the chapter ‘Section-selectors’ in the IAR C/C++ Development Guide.

 

All product names are trademarks or registered trademarks of their respective owners.

Realated Tech Notes

© IAR Systems 1995-2017 - All rights reserved.