Executable programs consists of a number of program sections. Typically there will be program sections for code, initialised data and zero'd data. There will often be more than one code section and these will require placement at specific addresses in memory.
To describe how the program sections of your program are positioned in memory the CrossWorks project system uses a memory map file and a section placement file. These files are both xml files and can be edited either with the text editor or with the built-in memory map editor. The memory map file specifies the start address and size of memory segments of the target. The section placement file specifies where to place program sections in the memory segments of the target. Seperating the memory map from the section placement scheme enables a single hardware description to be shared across projects and also enables a project to be built for a variety of hardware descriptions.
For example a memory map file representing a device with two memory segments called FLASH and SRAM would look something like this in the memory map editor.
ROOT FLASH 0x40000000 0x1000 SRAM 0x00000000 0x1000
A corresponding section placement file will refer to the memory segments of the memory map file and list the sections that are to be placed in those segments. This is done using a memory segment name in the section placement file that matches a memory segment name in the memory map file.
For example a section placement file that places a section called .stack in the SRAM segment and the .vectors and .text section int the FLASH segment would look like this in the memory map editor.
ROOT FLASH .text .vectors SRAM .stack
Note that the order of section placement within a segment is from the bottom up when viewed in the memory map editor, in this example .vectors is placed before .text.
The memory map file and section placement file to use for linkage can either be included as a part of the project or alternatively they can be specified the linker properties of the project.
You can create a new program section using the either the assembler or the compiler. For the C/C++ compiler this can be achieved using __attribute__ on declarations. For example
void foobar(void) __attribute__ ((section(".foo")));will allocate foobar in the section called .foo. Alternatively you can specify the section names of the code, constant, data and zero'd data for an entire compliation unit using the section options properties.
You can place the section into the section placement file using the memory map editor. If you are modifying a section placement file that is supplied in the CrossWorks distribution you will need to import it into your project using the project explorer.
With the section placement file in the memory map editor you can right click on the memory segment in which you wish to place the section and select New Program Section from the context menu. Right click on the new program section and select Properties from the context menu. In the properties window you can specify the Name which should correspond to the name used when you created the section. You will also need to specify the Input Sections property to match the name. In the simplest case this will be the *(Name). Using the context menu you can move the section within the segment to specify the order in which it should be placed.
Sections containing code and constant data should have their Load property set to be "Yes". There are sections that don't require any loading such as stack sections and zero'd data sections, these sections should have the Load property set to "No".
There are sections that are loaded but then need to be copied to sections that aren't loaded. This is required for initialised data sections and to copy code from slow memory regions to faster ones. To do this the Section To Run In property should contain the name of a section in the section placement file that the section will be copied to.For example initialised data is loaded into the section .data_load and then copied into the .data_run section.
ROOT FLASH .data_load Load=Yes, Section To Run In=.data_run .text .vectors SRAM .data_run Load=No .stack
The startup code will need to copy the contents of the .data_load section to the .data_run. To enable this symbols for each section marking the start and end addresses are generated. Each section will have a start symbol generated called __section name_start__ and an end symbol generated called __section name_end__. These symbols can be used to copy the sections from their load positions to their run positions
For example the .data_load section can be copied to the data_run section using the following call to memcpy.
memcpy(__data_run_start__, __data_load_start__, __data_load_end__ - __data_load_start__);
If you create a section that needs to be copied then you will need to modify the startup code to do the initialisation.