In Linux, the cmd file is the link command file, which stores the configuration information of the linker and can be referred to as the command file; the function of the cmd file is to indicate how to link the program. The cmd file consists of two parts: MEMORY and SECTIONS: MEMERY is used to define the name, starting address and length of each memory block; SECTIONS is mainly used to describe which segment is mapped to which segment of storage space.
#The operating environment of this tutorial: linux7.3 system, Dell G3 computer.
cmd files are linker command files (Linker Command Files), ending with the suffix .cmd.
The professional name of CMD is linker configuration file, which stores the configuration information of the linker. We call it command file for short. As can be seen from its name, the purpose of this file is to specify how to link the program.
Then we know that when writing a TI DSP program, the program can be divided into many segments, such as text, bss, etc., and each segment has a different role. When actually running in the film, the location is also different. For example, text code should generally be placed in flash, while bss variables should be placed in ram. etc. However, for different chips, the starting and ending addresses of each memory are different. Moreover, the linker does not know where in which memory the user wants to place a certain section, especially a custom section. In order to tell the linker the allocation of the internal storage space of the chip to be used and the specific storage location of each section of the program, it is necessary to write a configuration file, that is, a CMD file.
cmd file consists of two parts: MEMORY (ie: memory) and SECTIONS (ie: segments). MEMERY is used to define the name, starting address and length of each memory block. SECTIONS is mainly used to describe which segment is mapped to which segment of storage space. MEMORY can be divided into PAGE0 (program storage space) and PAGE1 (data storage space), PAGE (ie: frame).
The segments mentioned above can be divided into two categories: initialized segments and uninitialized segments. The initialized segment contains the actual instructions and data and is stored in the program memory space. The uninitialized segment only reserves the address space of the variable. The uninitialized segment does not have real content. Data is written to the variable during the running of the program and stored in the data storage space. In C language, there are many defined segments, such as ".text", ".const", and ".system". For these defined segments, there are many explanations about them on the Internet, so I will not go into details here. This article will next introduce readers to how to define segments by themselves as a user.
Comments can be written in the cmd file, surrounded by "/*" and "*/", but "//" is not allowed ", this is different from C language.
To write cmd files we need to use two pseudo-instructions MEMORY and SECTIONS (must be capitalized).
The syntax of MEMORY and SECTION can be found online. This article will explain the contents of MEMORY and SECTION with specific examples.
Explain MEMORY based on the cmd file of F28335 used by the author.
MEMORY { PAGE 0: /* Program Memory */ /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */ ZONE0 : origin = 0x004000, length = 0x001000 /* XINTF zone 0 */ RAML0 : origin = 0x008000, length = 0x001000 /* on-chip RAM block L0 */ RAML1 : origin = 0x009000, length = 0x001000 /* on-chip RAM block L1 */ RAML2 : origin = 0x00A000, length = 0x001000 /* on-chip RAM block L2 */ RAML3 : origin = 0x00B000, length = 0x001000 /* on-chip RAM block L3 */ ZONE6 : origin = 0x0100000, length = 0x100000 /* XINTF zone 6 */ ZONE7A : origin = 0x0200000, length = 0x00FC00 /* XINTF zone 7 - program space */ FLASHH : origin = 0x300000, length = 0x008000 /* on-chip FLASH */ FLASHG : origin = 0x308000, length = 0x008000 /* on-chip FLASH */ FLASHF : origin = 0x310000, length = 0x008000 /* on-chip FLASH */ FLASHE : origin = 0x318000, length = 0x008000 /* on-chip FLASH */ FLASHD : origin = 0x320000, length = 0x008000 /* on-chip FLASH */ FLASHC : origin = 0x328000, length = 0x008000 /* on-chip FLASH */ FLASHA : origin = 0x338000, length = 0x007F80 /* on-chip FLASH */ CSM_RSVD : origin = 0x33FF80, length = 0x000076 /* Part of FLASHA. Program with all 0x0000 when CSM is in use. */ BEGIN : origin = 0x33FFF6, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */ CSM_PWL : origin = 0x33FFF8, length = 0x000008 /* Part of FLASHA. CSM password locations in FLASHA */ OTP : origin = 0x380400, length = 0x000400 /* on-chip OTP */ ADC_CAL : origin = 0x380080, length = 0x000009 /* ADC_cal function in Reserved memory */ IQTABLES : origin = 0x3FE000, length = 0x000b50 /* IQ Math Tables in Boot ROM */ IQTABLES2 : origin = 0x3FEB50, length = 0x00008c /* IQ Math Tables in Boot ROM */ FPUTABLES : origin = 0x3FEBDC, length = 0x0006A0 /* FPU Tables in Boot ROM */ ROM : origin = 0x3FF27C, length = 0x000D44 /* Boot ROM */ RESET : origin = 0x3FFFC0, length = 0x000002 /* part of boot ROM */ VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of boot ROM */ PAGE 1 : /* Data Memory */ /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */ /* Registers remain on PAGE1 */ BOOT_RSVD : origin = 0x000000, length = 0x000050 /* Part of M0, BOOT rom will use this for stack */ RAMM0 : origin = 0x000050, length = 0x0003B0 /* on-chip RAM block M0 */ RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */ RAML4 : origin = 0x00C000, length = 0x001000 /* on-chip RAM block L1 */ RAML5 : origin = 0x00D000, length = 0x001000 /* on-chip RAM block L1 */ RAML6 : origin = 0x00E000, length = 0x001000 /* on-chip RAM block L1 */ RAML7 : origin = 0x00F000, length = 0x001000 /* on-chip RAM block L1 */ ZONE7B : origin = 0x20FC00, length = 0x000400 /* XINTF zone 7 - data space */ FLASHB : origin = 0x330000, length = 0x008000 /* on-chip FLASH */ }
You can see that MEMORY usually contains PAGE0 and PAGE1. RAML0 in PAGE0 represents the storage space with a starting address of 0x008000 and a storage space length of 0x001000. In the same way, we can know the meanings of other storage space names.
Comparing the TI28335 chip data manual (only part of it is intercepted), we can see that the writing of the above cmd file is based on the memory mapping section of the TI28335 chip data manual. We can also refer to the memory mapping section in the chip data manual to write the cmd file.
Next, the author will explain the content contained in SECTION. Also taking the cmd file of F28335 as an example
SECTIONS { /* Allocate program areas: */ .cinit : > FLASHA PAGE = 0 .pinit : > FLASHA, PAGE = 0 .text : > FLASHA PAGE = 0 codestart : > BEGIN PAGE = 0 ramfuncs : LOAD = FLASHD, RUN = RAML0, LOAD_START(_RamfuncsLoadStart), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), LOAD_SIZE(_RamfuncsLoadSize), PAGE = 0 csmpasswds : > CSM_PWL PAGE = 0 csm_rsvd : > CSM_RSVD PAGE = 0 /* Allocate uninitalized data sections: */ .stack : > RAMM1 PAGE = 1 .ebss : > RAML4 PAGE = 1 .esysmem : > RAMM1 PAGE = 1 /* Initalized sections go in Flash */ /* For SDFlash to program these, they must be allocated to page 0 */ .econst : > FLASHA PAGE = 0 .switch : > FLASHA PAGE = 0 /* Allocate IQ math areas: */ IQmath : > FLASHC PAGE = 0 /* Math Code */ IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD /* Uncomment the section below if calling the IQNexp() or IQexp() functions from the IQMath.lib library in order to utilize the relevant IQ Math table in Boot ROM (This saves space and Boot ROM is 1 wait-state). If this section is not uncommented, IQmathTables2 will be loaded into other memory (SARAM, Flash, etc.) and will take up space, but 0 wait-state is possible. */ /* IQmathTables2 : > IQTABLES2, PAGE = 0, TYPE = NOLOAD { IQmath.lib<IQNexpTable.obj> (IQmathTablesRam) } */ FPUmathTables : > FPUTABLES, PAGE = 0, TYPE = NOLOAD /* Allocate DMA-accessible RAM sections: */ DMARAML4 : > RAML4, PAGE = 1 DMARAML5 : > RAML5, PAGE = 1 DMARAML6 : > RAML6, PAGE = 1 DMARAML7 : > RAML7, PAGE = 1 /* Allocate 0x400 of XINTF Zone 7 to storing data */ ZONE7DATA : > ZONE7B, PAGE = 1 /* .reset is a standard section used by the compiler. It contains the */ /* the address of the start of _c_int00 for C Code. /* /* When using the boot ROM this section and the CPU vector */ /* table is not needed. Thus the default type is set here to */ /* DSECT */ .reset : > RESET, PAGE = 0, TYPE = DSECT vectors : > VECTORS PAGE = 0, TYPE = DSECT /* Allocate ADC_cal function (pre-programmed by factory into TI reserved memory) */ .adc_cal : load = ADC_CAL, PAGE = 0, TYPE = NOLOAD }
You can see that SECTION contains Various section names. Take ".text" as an example. ".text" is the binary instruction code segment generated after compilation. You can see that we allocate the content in ".text" to FLASHA for storage, and FLASHA is located at PAGE0 in MEMORY.
The ramfuncs in SECTION are related to the startup of 28335. Its essence is to read the user code from FLASH through the "bootstrap program" when powering on, save it in RAM and run it in RAM, thereby solving the problem of ROM The reading and writing speed is slow, and it is difficult to meet the problem of data loss due to high-speed smart chips and RAM power failure.
What use does knowing this information about the segment have for our users? The most direct use is that when the compiler prompts that the memory memory is insufficient, we can find the corresponding storage space through the corresponding segment name and modify the size of its storage space to meet the needs of our program. We can even store our code and data by customizing segment names.
Pass #pragma DATA_SECTION (function name or global variable name, "user-defined segment name in data space") or #pragma CODE_SECTION (function name or global variable name, "user-defined segment name in program space") Segment name") can implement customized segment names, thereby freely allocating storage space.
#pragma DATA_SECTION (for variables)
#pragma CODE_SECTION(用于函数)
但使用以上指令时需注意:不能在函数体内声明必须在定义和使用前声明,#pragma可以阻止对未调用的函数的优化。
下面结合实际使用例子来具体讲解:
#pragma DATA_SECTION(FFT_output, "FFT_buffer1"); float FFT_output[FFT_SIZE];
笔者声明了一个数据段,段名为FFT_buffer1,段的内容在变量FFT_ouput里。而声明后才定义变量FFT_output的大小。
我们如果想要使用这个自定义的段,接下来我们还要在CMD文件的SECTION中指定FFT_buffer1的存储空间。
FFT_buffer1 : > RAML4, PAGE = 1
通过以上几条语句,笔者实现了将变量的内容存放入指定的RAML4存储空间的操作。
从上可以得出,当全局变量所占内存过大时,我们可以通过自定义段选择有所余裕的存储空间的方式,从而来解决内存不足的问题。
相关推荐:《Linux视频教程》
The above is the detailed content of What is cmd file in Linux. For more information, please follow other related articles on the PHP Chinese website!