1 / 50

实时信号处理系统设计

实时信号处理系统设计. 第四讲 DSP 的软件开发 (2). 联系方式 :zyh@ccee.cqu.edu.cn 重庆大学通信工程学院. 本节内容. 1.C6000 的 C/C++ 实现. 2.C6000 的汇编相关. 3.C6000 的混合编程.. 开 发 流 程. 对 C/C++ 的支持.

dane
Download Presentation

实时信号处理系统设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 实时信号处理系统设计 第四讲 DSP的软件开发(2) 联系方式:zyh@ccee.cqu.edu.cn 重庆大学通信工程学院

  2. 本节内容 1.C6000的C/C++实现. 2.C6000的汇编相关. 3.C6000的混合编程.

  3. 开发流程

  4. 对C/C++的支持 • The TMS320C6000 C/C++ compiler supports the C/C++ language standardthat was developed by a committee of the American National Standards Institute(ISO) to standardize the C programming language. • The C++ language supported by the C6000 is defined by the ISO/IEC14882–1998 standard with certain exceptions.

  5. TMS320C6000 C/C++ Data Types

  6. 数据转换 • Float-to-integer conversions truncate toward 0. • Pointers and integers can be freely converted.

  7. 关键字 The C6000 C/C++ compiler supports the standard const, register, restrict, and volatile keywords. In addition, the C6000 C/C++ compiler extends the C/C++ language through the support of the cregister, interrupt, near, and far keywords.

  8. The const Keyword const关键字用于限定变量,数组等,以确保此值不被改变.可以优化你的代码,可以对于一些数据对象分配存储器进行控制.与#define的区别(有语法检查)? For example,the first statement below defines a constant pointer p to a variable int. The second statement defines a variable pointer q to a constant int: int * const p = &x; const int * q = &x;

  9. Const 的使用 Using the const keyword, you can define large constant tables and allocatethem into system ROM. For example, to allocate a ROM table, you could usethe following definition: far const int digits[] = {0,1,2,3,4,5,6,7,8};   一般来说如果数据不需要修改,都定义为const类型.

  10. Const 的例外 If you define an object as far const, the .const section allocates storagefor theobject. The const data storage allocation rule has two exceptions: • If the keyword volatile is also specified in the definition of an object (for example, volatile const int x). Volatile keywords are assumed to be allocatedto RAM. (The program does not modify a const volatile object, but something external to the program might.) • If the object has automatic storage (allocated on the stack).

  11. The cregister Keyword Cregister关键字是在c/c++上的扩展,它允许高级语言访问控制寄存器.当使用了此关键字,编译器首先对比标准控制寄存器.在使用相应代码代替.

  12. 有效的标准控制寄存器

  13. 使用方法: extern cregister volatile unsigned int AMR; extern cregister volatile unsigned int CSR; extern cregister volatile unsigned int IFR; extern cregister volatile unsigned int ISR; extern cregister volatile unsigned int ICR; extern cregister volatile unsigned int IER; extern cregister volatile unsigned int FADCR; extern cregister volatile unsigned int FAUCR; extern cregister volatile unsigned int FMCR; main() { printf(”AMR = %x\n”, AMR); }

  14. The interrupt Keyword Interrupt控制字也是编译器添加的专门用于中断函数的控制字. interruptvoid int_handler() { unsigned int flags; ... }

  15. Static static 声明的变量在C语言中有两方面的特征:1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

  16. static 1.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度; 2.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;

  17. near and far Keywords    主要用于指定全局或局部变量的访问以及函数的调用.编译器默认都为near访问(变量及函数). far static int x; static near int x; static int far x; far int foo(); static far int foo();

  18. Near and far data objects near keyword:The compiler assumes that the data item can be accessed relative to the data page pointer. For example: LDW *dp(_address),a0 far keyword :The compiler cannot access the data item via the dp. This can be required if the total amount of program data is larger than the offset allowed (32K) from the DP. For example: MVKL _address,a1 MVKH _address,a1 LDW *a1,a0    一旦你的变量使用了此关键字声明,则其他访问到此变量的地方都得加上此关键字.

  19. Near and far function calls Function calls can be invoked in one of two ways: near keyword :The compiler assumes that destination of the call is within± 1 M word of the caller. Here the compiler uses the PCrelativebranch instruction. B _func far keyword :The compiler is told by the user that the call is not within ± 1 M word. MVKL _func,a1 MVKH _func,a1 B a1

  20. Near&far相关编译选项 The –mrn option controls how run-time-support functions are called: –mr0 数据调用使用near方式. –mr1 数据调用使用far方式. 使用此选项后忽略ml选项. • Large model option (–ml) • –ml/–ml0 Aggregate data (structs/arrays) default to far • –ml1 All calls default to far • –ml2 All aggregate data and calls default to far • –ml3 All calls and all data default to far

  21. The restrict Keyword Restrict关键字主要用于限定指针或数组的存储相关性,主要为了更好的优化程序. void func1(int * restrict a, int * restrict b) { /* func1’s code here */ }   上式告诉编译器,a,b指向的数据区肯定不重叠,所以可以使用流水线操作.

  22. restrict void func2(int c[restrict], int d[restrict]) { int i; for(i = 0; i < 64; i++) { c[i] += d[i]; d[i] += 1; } }

  23. The volatile Keyword    编译器编译的时候一般尽量减少对存储器的访问,所以一般都假设数据是在内部的.但是有时候需要更新数据,为了保证代码不被优化掉,需要加上volatile关键字.

  24. 使用方法 unsigned int *ctrl; while (*ctrl !=0xFF); 如果没有restrict? 需要修改: volatile unsigned int *ctrl;

  25. Pragma Directives(编译指示) CODE_SECTIONDATA_ALIGN DATA_MEM_BANKDATA_SECTION FUNC_CANNOT_INLINEFUNC_EXT_CALLED FUNC_INTERRUPT_THRESHOLDFUNC_IS_PURE FUNC_IS_SYSTEMFUNC_NEVER_RETURNS FUNC_NO_GLOBAL_ASGFUNC_NO_IND_ASG INTERRUPTMUST_ITERATE NMI_INTERRUPTPROB_ITERATE STRUCT_ALIGNUNROLL

  26. The CODE_SECTION Pragma #pragma CODE_SECTION (symbol, ”section name”); #pragma CODE_SECTION(fn, ”my_sect”) int fn(int x) { return x; }   当你有代码需要单独连接到一个程序段,而不是一般的.text段的时候非常有用.

  27. The DATA_ALIGN Pragma #pragma DATA_ALIGN (symbol, constant);   数据对准,校正.用于数据存储访问的时候,定位在某个边界上.

  28. The DATA_SECTION Pragma #pragma DATA_SECTION (symbol, “section name”); DATA_SECTION指令告诉编译器把symbol分配到section name中去.当你想把数据单独分配到某个段中,而不是.bss段的时候非常有用.

  29. DATA_SECTION #pragmaDATA_SECTION(bufferB, ”my_sect”) char bufferA[512]; char bufferB[512]; 对应汇编程序: .global _bufferA .bss _bufferA,512,4 .global _bufferB _bufferB: .usect ”my_sect”,512,4

  30. The MUST_ITERATE Pragma MUST_ITERATE告诉编译器循环的的属性.但是这些属性必须是真实的。不然程序可能运行出错.     此指令主要用于优化C函数循环,一般情况下,只要有循环都最好带上此指令.以优化编译,加快程序执行的效率. #pragma MUST_ITERATE (min, max, multiple); Multiple参数必须带有.

  31. MUST_ITERATE #pragma MUST_ITERATE(10,10); for(i = 0; i < trip_count; i++) { ... (如果没有声明,则可能产生loop-bypassing代码.) #pragma MUST_ITERATE(8, 48, 8); for(i = 0; i < trip_count; i++) { ...

  32. MUST_ITERATE for(i2 = ipos[2]; i2 < 40; i2 += 5) { ... The compiler would have to generate a divide function call to determine, at runtime, the exact number of iterations performed. The compiler will not do this. In this case, using MUST_ITERATE to specify that the loop always executes8 times allows the compiler to attempt to generate a software pipelined loop: #pragma MUST_ITERATE(8, 8); for(i2 = ipos[2]; i2 < 40; i2 += 5) { ...

  33. C总结 对于DSP中的C语言,使用上与标准C并无区别,主要是要学会使用与硬件编程相关的一些关键字,以及CCS中专用的一些键字,编译指示等.

  34. 汇编程序 一行汇编代码可能包含成分: • Label • Parallel bars • Conditions • Instruction • Functional unit • Operands • Comment

  35. Label Labels must meet the following conditions: • The first character of a label must be a letter or an underscore (_) followed by a letter. • The first character of the label must be in the first column of the text file. • Labels can include up to 32 alphanumeric characters.

  36. Parallel Bars • 表示一条指令与上条指令并行执行 (||).

  37. Conditions • C6000中所有指令都可条件执行,对于C62X/C7X, A1, A2, B0, B1, B2可用作条件寄存器,C64X, A0,A1, A2, B0, B1, B2共6个.

  38. Instructions 指令包括: • 汇编器指令,如.text,.bss,.short,.def,.ref等. • 宏指令,与C的宏类似. • 汇编语言指令,abs,mvk等. 请参考: TMS320C6000 Assembly Language Tools User’s Guide, TMS320C6000 CPU and Instruction Set User’s Guide.

  39. Operands 操作必须有目的操作,有一到两个源操作,其中目的操作数必须与其中一个源操作数一致.使用x表示数据取自不同的积存器组.如:

  40. Comments • A comment may begin in any column when preceded by a semicolon (;). • A comment must begin in first column when preceded by an asterisk (*). • Comments are not required but are recommended.

  41. 汇编程序实例(1) unused .macro id .global unused:id: unused:id: b unused:id: ; nested branches to block interrupts nop 4 b unused:id: nop 5 .endm .sect ".vectors" .ref _c_int00 ; C entry point .align 32*8*4 ; must be aligned on 256 word boundary RESET: ; reset vector mvkl _c_int00,b0 ; load destination function address to b0 mvkh _c_int00,b0 b b0 ; start branch to destination function

  42. 汇编程序实例(1) 续上页 mvc PCE1,b0 ; address of interrupt vectors mvc b0,ISTP ; set table to point here nop 3 ; fill delay slot nop nop ; plug unused interrupts with infinite loops to ; catch stray interrupts unused 1 unused 2 …. unused 14 unused 15

  43. 汇编程序实例(2) .global _load .text N .set 1000 _load: mv a4, b0 ; use b0 as loop counter [!b0] b lend mvk N,b1 mpy b1,b0,b0 nop shru b0,3,b0 ; (loop counter)= (# loops)/8 loop: sub b0,1,b0 nop [b0] b loop nop 5 lend: b b3 nop 5 ; return .end

  44. 汇编程序实例(2) ; This function simulates a load on the DSP by executing N * loopCount ; instructions, where loopCount is the input parameter to load(). ; ; void _load(int loopCount) ; ; The loop is using 8 instructions. One instruction for sub, nop and ; b, plus nop 5. The extra nop added after sub is to make the number ; of instructions in the loop a power of 2.

  45. 混合编程 • Use separate modules of assembled code and link them with compiled C/C++ modules • Use intrinsics in C/C++ source to directly call an assembly language statement • Use inline assembly language embedded directly in the C/C++ source • Use assembly language variables and constants in C/C++ source

  46. 使用单独函数

  47. 使用intrinsics int x1, x2, y; y = _sadd(x1, x2); 参考TMS320C6000 Optimizing Compiler User's Guide p253-262

  48. 使用asm() asm(”;*** this is an assembly language comment”); 直接嵌入,不检查,建议尽量少用.

  49. C中使用汇编语言变量

  50. C中使用汇编语言变量 • 1) Use the .bss or .usect directive to define the variable. • 2) When you use .usect, the variable is defined in a section other than .bss • and therefore must be declared far in C. • 3) Use the .def or .global directive to make the definition external. • 4) Precede the name with an underscore in assembly language. • 5) In C/C++, declare the variable as extern and access it normally.

More Related