1.PRMFile structure
The PRM file consists of six components based on the different information contained. Here we only discuss the three components closely related to the memory space ing.
Define and divide all available memory resources of the chip, including program space and data space. Generally, we define a program space as ROM and a data space as Ram. However, these names are not keywords reserved by the system and can be modified by users at will. You can also split the memory space into blocks by address and attribute, and each block can be named freely. For example, different attributes can be used for the same Ram, so that after resetting, the variables can be cleared or not cleared.
The specific methods for memory division are described later.
Specify the various segments defined in the assigned source program, such as the Data Segment data_seg, const_seg, and code_seg, to which memory block the code segment code_seg is placed. It is a bridge linking the definition description in the source program with the actual physical memory.
Defines the length of the system stack. The subsequent length bytes can be modified based on actual application requirements. The actual location of the stack depends on the division and usage of RAM memory. By default, the stack is placed in the starting part of the ram region. Of course, you can use the stacktop keyword instead of this method. It will be discussed in detail later.
2Memory Partitioning Method
From segments to end, you can add any definition of memory division for multiple rows in the middle. Each row ends with a semicolon. The syntax type of the defined row is:
[Block name] = [attribute 1] [attribute 2],… , [Attribute N] [start address] to [end address];
Where,
- The definition of "Block name" is the same as that of C language variables. It is a string starting with an English letter. You can define a block name by yourself.
- "Attribute" users cannot define their own, because the attribute name specifies the different memory types and access methods corresponding to the "Block name" mentioned above, the types and access methods of different physical memory are certain.
For "attribute 1", codewarrior 5.0 can have three different types. For Read-Only Flash-Rom, the attribute must be read_only. For Read-Only Ram, the attribute can be read_write, it can also be no_init. The key difference between them is that the initialization code of the ANSI-C will automatically clear all global and static variables located in the read_write block, and the variables in the no_init block will not be automatically cleared. Of course, only resetting is not cleared, but it is still cleared when power is down. However, for single-chip microcomputer systems, it is sometimes critical that variables are not automatically cleared during resetting, it has special functions in some applications.
For "attribute 2... Attribute N, which can be viewed based on the. PRM sample file provided above. The possible formats include "data_far", "data_near", "ibcc_far", and "ibcc_near. "Data_far" corresponds to "data_near". When the memory area contains variables or constants (usually Ram, Flash, and EEPROM), you must specify one of the above two attributes, because of the memory paging, we can understand that the memory block specified by the "data_far" attribute is a non-fixed page that can store data, the memory block specified by the "data_near" attribute is a fixed page for storing data. Similarly, "ibcc_far" corresponds to "ibcc_near". When the memory area contains code (flash and EEPROM ), you must specify one of the preceding two attributes. The memory block specified by the "ibcc_far" attribute is a non-fixed page for saving code, the memory block specified by the "ibcc_near" attribute is a fixed page for saving code.
After discussion, the readers have discovered that. in the PrM file example, the attributes of RAM are "data_far" and "data_near", and the attributes of Flash are also four, however, only "data_far" and "ibcc_far" are available in the EEPROM, which exactly verifies the resource configuration mentioned in the previous article (resource configuration of the 16-bit microcontroller of Apsara stack, there are fixed pages in Ram and flash, but all the non-fixed pages in EEPROM.
- The starting address and ending address determine the physical location of a memory block. For fixed pages, they are expressed in 4-bit hexadecimal notation, whereas for non-fixed pages, it is represented in a 6-bit hexadecimal notation. The two more parameters are the value of the Register epage, rpage, or ppage. It can be seen that for paging resources, it is addressing through a combination of registers (epage, rpage, or ppage) and a 16-bit address bus.
"To" is a key reserved by the system and must be capitalized.
The following are some examples based on the content provided in the preceding example:
Example 1Ram = read_write data_near 0x2000 to 0x3fff;
The block name of the area allocated with 0x2000-0x3fff is "Ram" (of course, other names can be defined), which is known by the previous article, the physical memory of this region is Ram, the attribute should be "read_write", and the two pages in this region are fixed pages, so it is "data_near ".
Example 2Define the last 4 K bytes of the 8 K-byte RAM as a non-auto-cleared data retention zone, which should be defined as follows:
Segments
......
Ram = read_write data_near 0x2000 to 0x2fff;
Ram_no_init = no_init data_near 0x3000 to 0x3fff;
......
End
Note: The allocated addresses of each part of Ram should not overlap. Otherwise, an error will occur.
Example 3Eeprom_00 = read_only data_far ibcc_far 0x000800 to 0x000bff;
The EEPROM in the xs128 microcontroller is simulated by data-flash, so the attribute is read_only. All EEPROM are non-fixed pages, so "data_far" and "ibcc_far" are used ". The start address and end address are 6 hexadecimal numbers respectively. The first two "00" actually refer to the value of the eeprom paging register epage 0x00.
Segments is used to divide the physical memory of a single-chip microcomputer. The source program itself does not know the details of physical memory splitting and attribute definition. The two must be linked through the following placement.
3Placement of program and data segments
The information described in placement-end is to tell the memory block to which the various segments defined in the connector source program should be placed. The syntax type is:
[Segment name 1], [segment name 2],..., [segment name N] into [memory block name 1], [memory block name 2],… , [Memory block name N];
And
[Segment name 1], [segment name 2],..., [segment name N] distribute_into [memory block name 1], [memory block name 2],… , [Memory block name N];
Where
- The segment name is the name of the Data Segment, constant segment, or segment declared by "# pragma" in the source program. If the default name "default" is used, the default data segment name is default_ram, and the code segment and constant segment name is default_rom. If the segment name defined in the program is not mentioned in placement, it will be treated as default. Several segments with the same nature but different names can be placed in the same memory block and separated by commas.
- Into is the keyword reserved by the system. here it means "put.
- Distribute_into is also the reserved keyword of the system. Codewarrior has the function of automatic memory optimization, but this function is not enabled in "Small memory" mode, this function is enabled only when the 16-bit address space cannot store all variables and code.
In the segments-end area, when either of the four attributes "data_far", "data_near", "ibcc_far", and "ibcc_near" are added to the memory module attributes, in the placement-end area, you need to specify the segment names "Distribute", "const_distribute", and "data_distribute" (default, non-Keyword, which can be changed by the user) the allocated memory space, which requires the "distribute_into" keyword.
For more information about the automatic memory optimization function, see the official Freescale Technical Manual "tn 262.pdf ".
- The memory block name is the different memory block names divided by segments described earlier.
This intuitive description text allows you to conveniently and flexibly locate data or code to any possible location in the chip memory for some special purposes.
The following example illustrates the correspondence between segments, placement, and segments.
Example4 Define non-automatically cleared data segments
Segments
......
Ram = read_write data_near 0x2000 to 0x2fff;
Ram_no_init = no_init data_near 0x3000 to 0x3fff;
......
End
Placement
......
Data_persistent into ram_no_init;
......
End
// Compile the source program:
# Pragma data_seg data_persistent // defines non-custom data segments for resetting
Byte sysstate;
# Pragma data_seg default
4Stack settings
Codewarrior provides two methods for stack settings: "stacksize" and "stacktop. These two methods cannot exist in the same. PRM file at the same time. Stacksize is recommended when you only care about the size of the stack but not the storage location of the stack.
Stacksize is used by default.
StacksizeCommand method:
When the stacksize command is used, if "sstack into Ram" is declared in the placement-end part, the stack area is placed in the starting part of the ram area, the following example illustrates this method:
Example 5
Segments
......
Ram = read_write data_near 0x2000 to 0x3fff;
......
End
Placement
......
Sstack, paged_ram, default_ram into RAM;
......
End
StacksizeZero x 100
In the preceding example, the address of the stack region is 0x20ff-0x2000, and the initial Stack pointer points to the top stack address 0x20ff.
On the contrary, if "sstack into Ram" is not declared in the placement-end part, the stack is allocated after the allocated space in the ram area. See example 6.
Example 6
Segments
......
Ram = read_write data_near 0x2000 to 0x3fff;
......
End
Placement
......
Paged_ram, default_ram into RAM;
......
End
StacksizeZero x 100
In this example, if the allocated variable in the ram region occupies 4 bytes (from 0x2000 to 0x2003), the stack is placed behind the four bytes, from 0x2103 to 0x2004, the initial Stack pointer points to 0x2103.
StackyopCommand method:
When the stacktop command is used, if "sstack into Ram" is declared in the placement-end part, the stack zone is placed in the starting part of the ram area, the initial stack top is specified by stacktop. If no declaration is made, the initial stack top is specified by stacktop, And the stack size is set by the compiler based on the processor. The stack size is sufficient to hold the PC register value of the processor.
Memory Partitioning Method
1. From "segments" to "end", you can add a definition of any multi-row memory division in the middle. Each row ends with a semicolon. Syntax type of the defined row: [block name] = [attribute] [Starting address] to [ending address];
Where,
1. The definition of "Block name" is the same as that of C language variables. It is a string starting with an English letter.
2. "attributes" can be of three different types. For Read-Only Flash-Rom areas, the attribute must be "read_only". For read/write Ram areas, the attribute can be "read_write" or "no_init ". The key difference between them is that the initialization code of the ANSI-C will automatically clear all global and static variables located in the "read_write" block, and the variables in the "no_init" block will not be automatically cleared. For single-chip microcomputer systems, it is sometimes critical that variables are not automatically cleared during resetting.
3. The starting address and ending address determine the physical location of a memory block, expressed in hexadecimal notation.
4. to divide a global address space, add single quotation marks and G to the address to indicate the global address.
For example, eee_d_flash = read_only 0x0000400 'G to 0x0000fff' g;
"Segments" is used to divide the physical memory of a single-chip microcomputer. The source program itself does not know the details of physical memory splitting and attribute definition. The two must be connected through the "placement" below.
Ii. Placement of program segments and data segments
The information described in "placement-end" indicates the memory block to which the various segments defined in the connector source program should be placed. Syntax type: [segment name 1], [segment name 2],... [segment name N] into [memory block name];
Where
1. The segment name is the name of the Data Segment, constant segment, or code segment declared in the source program with "# pragma. If the default name "default" is used, the default data segment name is default_ram, and the code segment and constant segment name is default_rom. If the segment name defined in the program is not mentioned in placement, it will be treated as default. Several segments with the same nature but different names can be placed in the same memory block, separated by commas. Into is the keyword reserved by the system. Here it refers to "put.
2. The memory block name is the different memory block names divided by "segments" described earlier. Using this intuitive description text, you can easily and flexibly locate your data or code to any possible location in the chip memory for some special purposes. The following example shows the correspondence between segments, placement, and segments.
In this case, let's take an example. Finally, let's talk about align.
For example, Ram = read_write 0x2000 to 0x3fff align 2 [1:1];
Here, align 2 [] means placing the address of the variable in the even address alignment.
See the following example:
Here, the constant storage method is not good, at least my cw5.1 + xs128 is not good, and the feasible method is still searching.
Both Ram and ROM can be initialized in the PrM file:
/* non-paged RAM */
RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3EFF;
MYRAM = READ_WRITE 0x3F00 TO 0x3FFF FILL 0x10 0x20 0x30 0x40 0x50 0x60 0x70;
/* non-banked FLASH */
MYROM = READ_ONLY DATA_NEAR IBCC_NEAR 0x4000 TO 0x44FF FILL 0x11 0x22 0x33 0x44;
ROM_4000 = READ_ONLY DATA_NEAR IBCC_NEAR 0x4500 TO 0x7FFF;
ROM_C000 = READ_ONLY DATA_NEAR IBCC_NEAR 0xC000 TO 0xFEFF;
However, the initialization must be a custom code segment or data segment. The original system definition is not acceptable.
For example, myram has been initialized as shown above, but a variable Vara is defined as shown in the figure above.
How is the space allocated?
At this time, 0x3f00 is the variable VARA, and the initial value starts from 0x3f01.