DSP programming skills--Detailed explanation of cmd files

Publisher:创新脑细胞Latest update time:2014-08-12 Source: 互联网Keywords:DSP Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
  The cmd file is used to indicate how each data, symbol, etc. is divided into each segment and the storage space used by each segment when linking each target file after compilation. Many people are afraid of cmd files and find it difficult to understand the meaning of each segment, especially when there is no problem in program compilation, but it is easier to be at a loss when an error occurs when linking to generate an executable .out file, so let's explain the specific meaning of cmd files in detail.

  The C28x compiler divides the storage space into two parts for management, including:

  1. Program storage space: contains executable code, initialized records, and tables used by switch-case.

  2. Data storage space: contains external variables, static variables and system stack; generally, the storage space corresponding to each register is also classified in the data space.

  For the convenience of management, different types of code and variables are often allocated to different sections. Then the division of storage space becomes a problem of allocating addresses to the sections. For example, in the following code, it is specified that the .text section will be stored in RAML1 under Page0 in RAM. The starting address of RAML1 is 0x009000 and the length is 0x001000.

  MEMORY

  {

  /* Omit code that is not shown here */

  PAGE 0 :

  RAML1 : origin = 0x009000, length = 0x001000

  RAML2 : origin = 0x00A000, length = 0x001000

  /* Omit code that is not shown here */

  }

  SECTIONS

  {

  /* Omit code that is not shown here */

  .text : > RAML1, PAGE = 0

  /* Omit code that is not shown here */

  }

  In general, our code is not so large that it cannot be stored, but it is also possible that the code is too large to be stored, resulting in a link error such as the actual size of .text is size xxx, but the size of RAML1 is only yyy, so that the output file cannot be generated. At this time, we can increase the length of RAML1 corresponding to the above, that is, length, so that the address space allocated to the .text segment becomes larger. However, after the address space of RAML1 is expanded, it occupies the space of RAML2, resulting in address overlap. At this time, the starting position of RAML2 should be moved back and its length should be reduced accordingly to avoid address overwrite errors; after modification, it can be:

  RAML1 : origin = 0x009000, length = 0x001500

  RAML2 : origin = 0x00A500, length = 0x000500

  Another solution is to allocate .text to other longer address spaces; if there is no existing segment with a longer address range, you can also merge existing segments. For example, delete RAML2 and merge all its addresses into RAML1, while .text is still allocated in RAML1. When deleting RAML2, please note that it can only be operated when it is not used by any segment, otherwise it will prompt that other segments cannot find the corresponding storage unit when compiling and linking.

  Below we explain the meaning of each segment:

  1. Initialization segment

  These contain data and executable code and are usually read-only. They include:

  1. cinit和.pinit

  Contains a table used to initialize variables and constants. It is read-only.

  C28x .cinit is limited to the 16-bit range, that is, the lower 64K range.

  2 .const

  This includes string constants, string literals, selection lists, and read-only variables defined with the const keyword (but excluding volatile types and assuming a small memory model).

  3 .econst

  Contains string constants, as well as global and static variables defined using the far keyword.

  4 .switch

  Stores the selection table used by the switch-case instruction.

  5 .text

  Usually read-only, contains all executable code, as well as constants generated by the compiler .

  2. Uninitialized segments

  Although uninitialized segments will not be initialized, they still need to reserve the relevant address space in the storage unit (usually RAM). They include:

  1 .bss

  Reserve storage space for global and static variables. When starting or loading the program, the C/C++ startup program will copy the data in the .cinit segment (usually stored in ROM) to the .bss segment.

  2. ebss

  Reserve storage space for global and static variables defined with the far keyword (applicable only to C code). When starting or loading the program, the C/C++ startup program will copy the data in the .cinit segment (usually stored in ROM) to the .ebss segment.

  3 .stack

  By default, the stack is stored in the .stack segment (refer to boot.asm), which is used to reserve storage space for the stack. The main functions of the stack are:

  1) Reserve storage space for storing parameters passed to the function;

  2) Allocate relevant address space for local variables;

  3) Save the state of the processor;

  4) Save the return address of the function;

  5) Save the values ​​of some temporary variables.

  It should be noted that the .stack segment can only use the data storage unit of the lower 64K address, because the CPU's SP register is 16 bits and it cannot read the address range exceeding 64K. In addition, the compiler cannot check the stack overflow error (unless we write some code to detect it ourselves), which will lead to wrong output results, so a relatively large storage space should be allocated for the stack, and its default value is 1K words. The operation of changing the stack size can be completed through the compiler option --stack_size.

  4. system

This article is cited

  Reserve storage space for dynamic memory allocation, thereby serving dynamic memory allocation routines such as malloc, calloc, realloc, and new. If these dynamic memory management functions are not used in C/C++ code, there is no need to create a .sysmem segment.

  In addition, we often mention the "stack". Here we only talk about the stack. What is the heap used for? The heap is used for dynamic memory allocation. Because RAM resources are still relatively precious on DSP , the storage space occupied by the heap cannot be expanded indefinitely. For the heap modified by the near keyword, the address space it occupies can only be up to 32K words at most; for the heap modified by the far keyword, the storage space it uses is automatically set by the compiler , and the default is only 1K words.

  5 .esysmem

  Allocate dynamic storage space for the far malloc function. If this function is not used, the compiler will not automatically create the .esysmem section.

  For the assembler, it will automatically create three sections: .text, .bss and .data. We can use #pragma CODE_SECTION and #pragma DATA_SECTION to create more sections.

  By default, the storage space allocated to each segment is configured as follows (can be changed as needed):

  Finally, let's take an example of memory address allocation corresponding to an ADC register to see how the completed cmd file is completed (in fact, the memory address allocation of all registers has been done for us in TI's peripheral and header file packages, and here is a demonstration).

  First, in the header file or source program that uses registers (or custom variables), specify a custom segment for the registers (or custom variables):

  #ifdef __cplusplus

  #pragma DATA_SECTION("AdcRegsFile")

  #else

  #pragma DATA_SECTION(AdcRegs,"AdcRegsFile");

  #endif

  volatile struct  ADC_REGS AdcRegs; //Make the structure allocated in the specified segment

  Then, in the cmd file, allocate the AdcRegsFile segment to the ADC memory area under SECTIONS , and define the starting position and length of the ADC memory area in MEMORY .

  MEMORY

  {

  PAGE 0: /* Program Memory */

  /* Omit the display of irrelevant content */

  PAGE 1: /* Data Memory */

  /* Omit the display of irrelevant content */

  ADC : origin = 0x007100, length = 0x000020 /* ADC registers */

  /* Omit the display of irrelevant content */

  }

  SECTIONS

  {

  /* Omit the display of irrelevant content */

  AdcRegsFile : > ADC, PAGE = 1

  /* Omit the display of irrelevant content */

  }

  The above is a complete example of customizing segments and specifying memory areas. If you do not need such customization, you can ignore it and use existing ones, such as the cmd file that can be used in an example.

Keywords:DSP Reference address:DSP programming skills--Detailed explanation of cmd files

Previous article:Design of serial communication system based on DSP and touch screen
Next article:DSP Programming Skills 17---Very "Critical" Keywords

Latest Embedded Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号