DSP

#pragma DATA_SECTION 和 #pragma CODE_SECTION的使用

2019-07-13 20:01发布

友情链接CCS CMD文件 
今天读DSP的图像采集程序,遇到了一点陌生的东西: ti的帮助文档里是这么讲的: The DATA_SECTION pragma allocates space for the symbol in asection called section name. 
The syntax for the pragma in C is: #pragma DATA_SECTION (symbol, "section name"); 我个人的理解是: 定义一个数据段: 
         段名为:    "sectionname"
         段的内容在: symbol 里 
在CCS编程中,如果我们不指定变量的存放位置,编译器会自动的给变量分配一个位置,但是如果有的时候需要把变量放在一个特定的空间内,我们应该如何操作呢,CCS提供了如下的两个指令
#pragma CODE_SECTION
#pragma DATA_SECTION
其中data_section是针对数据空间的,code_section是针对程序空间的,具体的使用办法是
#pragma DATA_SECTION(bufferB, ”my_sect”)
char bufferB[512];
在.cmd文件中建立对应的section就可以使用了。 注意:在使用#pragmaDATA_SECTION时,应该先开辟一个空间,即:#pragma DATA_SECTION(bufferB,”my_sect”),然后再定义该空间的大小:char bufferB[512]; #pragma,是一个编译控制指令,可以在编译时动态地调整编译选项,这种指令在不同的编译系统中是不同的. #pragma DATA_ALIGN( symbol,constant) 指令的作用是:排列排列symbol到constant指点的列边界上. #pragma DATA_ALIGN(rxdata_stream,   128)
就是让rxdata_stream地址的末尾7位是0(二进制地址),就是128字节对齐。
对齐的目的,一般是位了CACHE读写外存。
如果一个CACHE的line是128字节。这样,如果数据128字节对齐,那么取一个128字节的数据,只使用一个CACHE行就够了。 char efd;
#prgma DATA_ALIGN(efd, 8)
编译时一定会把efd变量的地址安排在8字节对齐的位置上,也即efd地址的低3位一定为0。
由于在基于DSP的嵌入式系统开发中,存储资源特别是片内高速存储资源有限,在算法系统集成时Memory的管理对于提高整个系统的优化是非常重要的,这一方面影响数据的读取、搬移速度;另一方面还影响Cache的命中率,下面分程序和数据两方面分析。     程序区:最大原则是将经常调度使用的算法模块放片内。为做到这点,TI的CCS中提供了#pragma CODE_SECTION,可以把需要单独控制存放的函数段从.text段中独立出来,从而在.cmd文件中对这些函数段进行单独物理地址映射。还可以使用程序动态的方式,将需要运行的代码段先调度进片内memory,如H.264/AVC中CAVLC和CABAC两个算法模块具有互斥性,因此可以将这两个算法模块放在片外而且对应于片内同一块运行区,在运行其中某一个算法模块之前,先将其调入片内,从而充分利用片内有限的高速存储区。程序区的管理考虑到一级程序Cache(L1P)的命中率,最好将具有先后执行顺序的函数按地址先后顺序配置在程序空间中,同时对代码比较大的处理函数将其拆分成小函数

 
 数据区:在视频标准编解码中,由于数据块都很大,如一帧D14:2:0的图像有622k大小,而且在编解码中都需要开3~5帧甚至更多的缓冲帧,因此数据基本上无法在片内存放。为此在系统的Memory优化管理中,需要开C64系列DSP的二级Cache(对于TMS320DM642用于视频编解码中二级Cache开64k的情况比较多)。同时最好将放片外的被Cache所映射的视频缓冲区的数据以128byte对齐,这是因为C64系列的DSP的二级Cache的每行大小为128 byte,以128byte对齐有利于Cache的刷新和一致性维护。

The DATA_SECTION pragma allocates space for the symbol in a section called section name. 
The syntax for the pragma in C is:
#pragma DATA_SECTION (symbol, "section name"); The syntax for the pragma in C++ is:
#pragma DATA_SECTION ( "section name");The DATA_SECTION pragma is useful if you have data objects that you want to link into an area separate from the .bss section.
This directive is illustrated in the following example.
Using the DATA_SECTION Pragma
a)    C source file
#pragma DATA_SECTION(bufferB, "my_sect") char bufferA[512]; char bufferB[512]; // 执行完此三条语句之后,数组bufferB被分配到段名为 "my_sect"的自定义段中
b)    C++ source file
char bufferA[512]; #pragma DATA_SECTION("my_sect") char bufferB[512];
c)    Assembly source file
.global _bufferA     .bss     _bufferA,512,4      .global _bufferB _bufferB: .usect   "my_sect",512,4          
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// The CODE_SECTION pragma allocates space for the func in a section named section name. The CODE_SECTION pragma is useful if you have code objects that you want to link into an area separate from the .text section.
The syntax of the pragma in C is:
#pragma CODE_SECTION (func, section name) The syntax of the pragma in C++ is: #pragma CODE_SECTION (section name) The following example demonstrates the use of the CODE_SECTION pragma. Using the CODE_SECTION Pragma a)     C source file char bufferA[80]; char bufferB[80]; #pragma CODE_SECTION(funcA, codeA) char funcA(int i); char funcB(int i); void main() { char c; c = funcA(1); c = funcB(2); } char funcA (int i) { return bufferA; } char funcB (int j) { return bufferB[j]; }
b)     Assembly source file .sect ".text" .global _main; *************************************************************** ;* FNAME: _main FR SIZE: 2 * ;* * ;* FUNCTION ENVIRONMENT * ;* * ;* FUNCTION PROPERTIES * ;* 0 Parameter, 1 Auto, 0 SOE * ;*************************************************************** _main: ADDB SP,#2 MOVB AL,#1 ; |12| LCR #_funcA ; |12| ; call occurs [#_funcA] ; |12| MOV *-SP[1],AL ; |12| MOVB AL,#1 ; |13| LCR #_funcB ; |13| ; call occurs [#_funcB] ; |13| MOV *-SP[1],AL ; |13| SUBB SP,#2 LRETR ; return occurs .sect "codeA" .global _funcA ;*************************************************************** ;* FNAME: _funcA FR SIZE: 1 * ;* * ;* FUNCTION ENVIRONMENT * ;* * ;* FUNCTION PROPERTIES * ;* 0 Parameter, 1 Auto, 0 SOE * ;*************************************************************** _funcA: ADDB SP,#1 MOV *-SP[1],AL ; |17| MOVZ AR6,*-SP[1] ; |18| ADD AR6,#_bufferA ; |18| SUBB SP,#1 ; |18| MOV AL,*+XAR6[0] ; |18| LRETR ;return occurs .sect ".text" .global _funcB ;*************************************************************** ;* FNAME: _funcB FR SIZE: 1 * ;* * ;* FUNCTION ENVIRONMENT * ;* * ;* FUNCTION PROPERTIES * ;* 0 Parameter, 1 Auto, 0 SOE * ;*************************************************************** _funcB: ADDB SP,#1 MOV *-SP[1],AL ; |22| MOVZ AR6,*-SP[1] ; |23| ADD AR6,#_bufferB ; |23| SUBB SP,#1 ; |23| MOV AL,*+XAR6[0] ; |23| LRETR ;return occurs // 从红 {MOD}标记可以看出,在加入#pragma CODE_SECTION(funcA, codeA)语句之后,main()函数和_funcB函数被 // 分配到 ".text" 段中,而_funcA函数被分配到 "codeA" 段中

参考:http://blog.sina.com.cn/s/blog_621c94960100ibqw.html
            http://blog.chinaunix.net/uid-26053577-id-1936473.html
            http://blog.sina.com.cn/s/blog_70c7b3780100zcid.html