Note: 1. I learned about ARM programming today, so I searched for a lot of information online, but found that there were not many that were really useful. And after my actual test, there were quite a few differences from what some experts on the Internet said.
2. Test environment WinXp RVDS2.2 compiler and connector
3. About the tools used for testing
1. Composition of ARM Program
The "ARM program" mentioned here refers to the program being executed in the ARM system, not the image file saved in ROM. The image file burned into ROM is not exactly the same as the ARM program when it is actually running.
An ARM program consists of 3 parts: RO, RW and ZI
RO: Instructions and constants in the program, ReadOnly read-only code segments and constants
RW: initialized variables in the program, ReadWrite global variables and static variables that can be read and written
ZI: is an uninitialized variable in the program, ZeroInit is the segment of the variable to be initialized to zero in the RW segment (that is, the segment is contained in RW)
The above three points are expressed in C language:
1. The instructions and constants in C are compiled into RO type data.
2. Uninitialized or initialized variables in C are ZI type data after compilation. (Note this)
3. Variables in C that have been initialized to non-zero values are RW type data after compilation.
I will illustrate the above with practical examples below.
2. Composition of ARM image files
The so-called ARM image file is actually an executable file, also known as an image file, also called an ELF file. It includes two formats, bin or hex, and can be directly burned into ROM for execution. During the AXD debugging process, we debug the .axf file, which is actually an image file. It just adds a file header and some debugging information to the bin file.
Image files are generally composed of domains, which are composed of up to three output segments (RO, RW, ZI), and the output segments are composed of input segments. The so-called domain refers to the area where the entire bin image file is located, which is divided into the loading domain and the running domain. The code we input generally has a code part and a data part, which is the so-called input segment. After compilation, it becomes the RO segment and RW segment in the bin file, and the so-called ZI segment, which is the output segment.
Loading domain: It is the area where the image is statically stored, generally refers to the entire bin file burned in the flash;
Running domain: Usually programs are moved to SDRAM to run, and the address space where the image is moved to SDRAM to work is the running domain.
For the output segments in the load domain, generally speaking, the RO segment is followed by the RW segment, and the RW segment is followed by the ZI segment. In the run domain, these output segments are not continuous, but RW and ZI must be connected. The data in the ZI segment and RW segment can actually be RW attributes.
Image files generally only contain RO and RW data. The reason why image files do not contain ZI data is that ZI data is always 0, so there is no need to include it. Just clear the area where ZI data is located before running the program. Including it will waste storage space.
In fact, the instructions in ROM should at least have the following functions:
1. Move RW from ROM to RAM. Because RW is a variable, variables cannot be stored in ROM.
2. Clear all RAM areas where ZI is located. Because the ZI area is not in the Image, the program needs to clear the corresponding RAM area according to the ZI address and size given by the compiler. ZI is also a variable, and similarly: variables cannot be stored in ROM
In the initial stage of program execution, the C program can access variables normally only after the instructions in RO complete these two tasks. Otherwise, only the code without variables can be executed.
3. Example Test
(1) RO segment test
The following two programs differ in one statement, which is to declare a character constant. Therefore, according to what we said before, the difference between them should only be the size of one statement in RO data.
Pro1:
1: #include
2: void main(void)
3: {
4: ;
5: }
Pro2:
1: #include
2: const char ch = 2; // constant
3: void main(void)
4: {
5: ;
6: }
Pro3:
1: #include
2: const char ch = 2;
3: int main(void)
4: {
5: return 0;
6: }
Pro1 compilation result:
Code (inc. data) RO Data RW Data ZI Data Debug
932 32 16 0 96 0 Grand Totals
932 32 16 0 96 0 Image Totals
================================================================================
Total RO Size (Code + RO Data) 948 ( 0.93kB)
Total RW Size (RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size (Code + RO Data + RW Data) 948 ( 0.93kB)
================================================================================
Pro2 compilation result:
Code (inc. data) RO Data RW Data ZI Data Debug
932 32 20 0 96 0 Grand Totals
932 32 20 0 96 0 Image Totals
================================================================================
Total RO Size (Code + RO Data) 952 ( 0.93kB)
Total RW Size (RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size (Code + RO Data + RW Data) 952 ( 0.93kB)
================================================================================
Pro3 compilation result:
Code (inc. data) RO Data RW Data ZI Data Debug
936 32 20 0 96 0 Grand Totals
936 32 20 0 96 0 Image Totals
================================================================================
Total RO Size (Code + RO Data) 956 ( 0.93kB)
Total RW Size (RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size (Code + RO Data + RW Data) 956 ( 0.93kB)
================================================================================
From the compilation results above (especially the red part), we can see that the constant is placed in the RO segment, which verifies the first point. When a statement is added, the size of the Code section increases.
(2) RW segment test
The only difference between Pro4 and Pro1 is "variables initialized to non-zero". According to what was said before, initialized variables should be counted in RW, so there should be a difference in the size of RW between the two programs.
Pro4:
1: #include
2: char a = 5;
3: void main(void)
4: {
5: ;
6: }
Pro5:
1: #include
2: char a = 0;
3: void main(void)
4: {
5: ;
6: }
Pro4 compilation result:
Code (inc. data) RO Data RW Data ZI Data Debug
932 32 16 4 96 0 Grand Totals
932 32 16 4 96 0 Image Totals
================================================================================
Total RO Size (Code + RO Data) 948 ( 0.93kB)
Total RW Size (RW Data + ZI Data) 100 ( 0.10kB)
Total ROM Size (Code + RO Data + RW Data) 952 ( 0.93kB)
================================================================================
Pro5 compilation result:
Code (inc. data) RO Data RW Data ZI Data Debug
932 32 16 4 96 0 Grand Totals
932 32 16 4 96 0 Image Totals
================================================================================
Total RO Size (Code + RO Data) 948 ( 0.93kB)
Total RW Size (RW Data + ZI Data) 100 ( 0.10kB)
Total ROM Size (Code + RO Data + RW Data) 952 ( 0.93kB)
================================================================================
Compared with Pro1, Pro4 only has 4 more bytes in the RW Data segment.
In Pro5, variables initialized to 0 are still placed in the RW area.
(3) ZI segment test
The difference between Pro5 and Pro1 is an uninitialized variable "a". From the previous understanding, it can be inferred that the only difference between the two programs should be the ZI size.
Pro5:
1: #include
2: char a;
3: void main(void)
4: {
5: ;
6: }
Pro5 compilation results:
Code (inc. data) RO Data RW Data ZI Data Debug
932 32 16 4 96 0 Grand Totals
932 32 16 4 96 0 Image Totals
================================================================================
Total RO Size (Code + RO Data) 948 ( 0.93kB)
Total RW Size (RW Data + ZI Data) 100 ( 0.10kB)
Total ROM Size (Code + RO Data + RW Data) 952 ( 0.93kB)
================================================================================
The actual situation is that uninitialized variables are placed in the RW area, not the ZI area.
IV. Conclusion
The above test found that ZI is not used at all. This is very puzzling. The following is the complete compilation file of Pro5
Previous article:JLink debugging method for S3C6410
Next article:S3C6410 SPI full-duplex read and write process analysis
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- The domestic operating system RT-Thread seems to be more powerful and can enter the automotive field
- Use of resolver decoding chip AD2S1200
- GaN goes mobile?
- Is there any MEMS or sensor expert?
- Leakage current and withstand voltage test of low voltage battery products
- MSP430 Registers
- BMS insulation detection circuit
- i.MX6ULL Embedded Linux Development 1-Preliminary Study on Uboot Transplantation
- 【Synopsys IP Resources】 Comprehensive IP Solutions to Help HPC Chip Development
- GPIO Features of TMS320C6748