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 compiler this can be achieved using one of the #pragma directives. For example:
#pragma codeseg(".foo") void foobar(void); #pragma codeseq(default)
This 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. 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".
If you create a section that needs to be copied then you will need to modify the startup code to do the initialisation.
You can specify that initialisation data is stored in the default program section using the .init directive and you can refer to the start and end of the section using the SFE and SFB directives. If for example you create a new data section called "IDATA2" you can store this in the program by putting the following into the startup code
data_init_begin2 .init "IDATA2"
data_init_end2
You can then use these symbols to copy the stored section information into the data section using (an assembly coded version of)
memcpy(SFB(IDATA2), data_init_begin2, data_init_end2-data_init_end2)