Executable programs consist of a number of sections. Typically, there are program sections for code, initialized data, and zeroed data. There is often more than one code section and they must be placed at specific addresses in memory.
To describe how the program sections of your program are positioned in memory, the CrossWorks project system uses memory-map files and section-placement files. These XML-formatted files are described in Memory Map file format and Section Placement file format. They can be edited with the CrossWorks text editor. The memory-map file specifies the start address and size of target memory segments. The section-placement file specifies where to place program sections in the target's memory segments. Separating 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 could look something like this in the memory-map editor.
<Root name="Device1"> <MemorySegment name="FLASH" start="0x10000000" size="0x10000" /> <MemorySegment name="SRAM" start="0x20000000" size="0x1000" />
A corresponding section-placement file will refer to the memory segments of the memory-map file and will list the sections to be placed in those segments. This is done by using a memory-segment name in the section-placement file that matches the corresponding 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 sections in the FLASH segment would look like this:
<Root name="Flash Section Placement"> <MemorySegment name="FLASH" > <ProgramSection name=".vectors" load="Yes" /> <ProgramSection name=".text" load="Yes" /> </MemorySegment> <MemorySegment name="SRAM" > <ProgramSection name=".stack" load="No" /> </MemorySegment> </Root>
Note that the order of section placement within a segment is top down; in this example .vectors is placed at lower addresses than .text.
The memory-map file and section-placement file to use for linkage can be included as a part of the project or, alternatively, they can be specified in the project's linker properties.
You can create a new program section using 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 names for the code, constant, data, and zeroed-data sections of an entire compilation unit by using the Section Options properties.
You can now place the section into the section placement file using the editor so that it will be located after the vectors sections as follows:
<Root name="Flash Section Placement"> <MemorySegment name="FLASH"> <ProgramSection name=".vectors" load="Yes" /> <ProgramSection name=".foo" load="Yes" /> <ProgramSection name=".text" load="Yes" /> </MemorySegment> <MemorySegment name="SRAM"> <ProgramSection name=".stack" load="No" /> </MemorySegment> </Root>
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.
Sections containing code and constant data should have their load property set to Yes. Some sections don't require any loading, such as stack sections and zeroed-data sections; such sections should have their load property set to No.
You can specify that initialization 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:
_data2_init_begin:: INIT "IDATA2" _data2_init_end::
You can then use these symbols to copy the stored section information into the data section using (an assembly-coded version of):
/* Section image located in flash */ extern const unsigned char data2_init_begin; extern const unsigned char data2_init_end; memcpy(SFB(IDATA2), data2_init_begin, data2_init_end-data2_init_end)