1、第十讲 DSP的C及汇编语言,2013,在CCS编程中,如果我们不指定变量的存放位置,编译器会自动的给变量分配一个位置。但是,如果有的时候需要把变量放在一个特定的空间内,我们应该如何操作呢?CCS提供了如下的两个指令: #pragma CODE_SECTION; #pragma DATA_SECTION;其中data_section是针对数据空间的,code_section是针对程序空间的。,一 DSP编程中#pragma DATA_SECTION,具体的使用办法是:#pragma CODE_SECTION(fn, ”my_sect”)int fn(int x) return c; #prag
2、ma DATA_SECTION(bufferB, ”my_sect”)char bufferA512;char bufferB512; / 可能有问题,没定义bufferA,在.cmd文件中建立对应的section就可以使用了: MEMORY PAGE 1: spacename : origin = 0x., length 0x. SECTIONS .my_sect : spacename PAGE 1 ,6,二 ioport,Ioport 关键字读写DSP的I/O端口空间。 ioport关键字的用法如下:Ioport type port hex_numioport是指定这是个端口变量的关键字
3、;type是指端口的数据类型,必须是char,short,int或unsigned;Port hex_num指的是 I/O 端口号, hex_num变量是一个十六进制数据。必须注意的是,所有的端口变量在函数级说明端口变矗是无效的,必须在支存级予以说明:同时在函数原型中不能使用ioport关键字。,7,下面的代码定义 I/O端口为unsigned port10h,将数据a写 port 10h,然后从port10h读人数据存到b中:,所有I/O端口的定义必须在文件级完成,不支持在函数级声明的I/O端口变量。利用ioport关键字定义的I/O端口变量可以象一般变量一样进行赋值操作,三 中断,同传统的
4、单片机中断处理方式类似,DSP中断的处理也有两种方式:(1)查询法:可以更好地对程序进程进行控制,对中断的处理可以完全按照程序预定的方式进行,,一般不会出现中断丢失或中断嵌套的问题,但由于中断发生时不会暂停当前正在执行的程序,而程序可能正处于复杂的处理或运算状态,只有结束当前处理才会去检查中断标志,因此中断实时性不容易保证。(2)回调法:程序结构更为清晰,而且当有中断发生的时候会暂停当前正在执行的程序,中断实时性可以得到保证,但如果中断处理函数实现不当容易造成中断丢失或中断嵌套问题,影响系统的正常运行。,采用回调法处理DSP中断需要定义中断服务函数,有两种方法:(1)用关键字intterupt
5、(中断)来实现。它的用法是:interrupt void isr (void);(2)任何具有名为c_intd 的函数(d为0到9的数),都被假定为一个中断程序。如:void c_int1 (void); 无论用哪种方法定义中断服务函数,都须注意以下问题:(1)中断处理函数必须是void类型,而且不能有任何输入参数。,(2)进入中断服务函数,编译器将自动产生程序保护所有必要的寄存器,并在中断服务函数结束时恢复运行环境。(3)进入中断服务函数,编译器只保护与运行上下文相关的寄存器,而不是保护所有的寄存器。中断服务函数可以任意修改不被保护的寄存器,如外设控制寄存器等。(4)要注意IMR、INTM等
6、中断控制量的设置。通常进入中断服务程序要设置相应寄存器将中断屏蔽,退出中断服务程序时再打开,避免中断嵌套。,(5)中断处理函数可以被其他C程序调用,但是效率较差。(6)多个中断可以共用一个中断服务函数,除了c_int0。c_int0是DSP软件开发平台CCS提供的一个保留的复位中断处理函数,不会被调用,也不需要保护任何寄存器。(7)使用中断处理函数和一些编译选项冲突,注意避免对包含中断处理函数的C程序采用这些编译选项。(8)中断服务函数可以和一般函数一样访问全局变量、分配局部变量和调用其它函数等。,(9)要利用中断向量定义将中断服务函数入口地址放在中断向量处以使中断服务函数可以被正确调用。(1
7、0)中断服务函数要尽量短小,避免中断丢失、中断嵌套等问题。,四 动态分配内存,TMS320C2000 C语言程序中可以调用malloc、calloc或realloc函数来动态分配内存。,动态分配内存概述,什么时候需要动态分配内存?实例:顺序对一批文件进行解析,但是不知道文件的大小,如何建立缓冲区?,malloc函数,malloc函数原型:void * malloc(size_t n);n是要分配的内存的大小,返回值是分配内存的块的首地址,malloc函数,例1:使用malloc函数分配一个可以容纳10个整型元素的内存空间,并将其用作一个整型数组,malloc函数,关键代码:int * arra
8、y;array = (int *)malloc(10 * sizeof(int);注意:内存大小不能写成数组元素的个数,malloc函数,例2:定义一个结构struct testint a;char b;int c10;使用malloc函数分配一个此种结构类型的对象,malloc函数,关键代码:struct test * p;p = (struct test *)malloc(sizeof(struct test);,需要注意的问题,(1)malloc函数是一个库函数,它并不是C语言中的关键字:需要头文件才可以使用该函数并不是所有的平台都可以使用该函数,尤其是一些单片机系统,需要注意的问题,(
9、2)指针类型转换是必须的,关系到接收分配好的内存块的地址可以向前看多少字节。如果不做指针类型转换会怎么样?void * 指针存在的意义。,需要注意的问题,(3)内存块大小的可移植性问题分配一个整型变量数组应使用:数组元素个数 * sizeof(int)确定内存块的大小问题:sizeof和strlen函数的区别,free函数,free函数原型:void free(void * p);p是要释放的已分配内存的块的首地址,free函数,释放一块动态分配的内存:例如:int *p;p = (int *)malloc(sizeof(int);free(p);,需要注意的问题,(1)free函数同样是一个
10、库函数(2)free函数的参数必须是一个由动态内存分配方法分配的内存块的首地址(使用malloc函数分配的内存),动态分配内存特点,内存空间大小可以是一个变量,其值在运行时确定内存空间在运行时分配,在程序结束时收回;内存的分配由操作系统参与完成动态分配的内存空间在未释放之前均可以被引用,保证其生命期,类malloc函数,calloc函数void *calloc( size_t num, size_t size ); relloc函数void *realloc(void *mem_address, unsigned int newsize);,综合实例,实现一个可变的数组,从一个键盘输入若干个数
11、字,以-1结尾。并将其逆序输出。提示:作为数组的缓冲区的大小是固定的,当读取的数字的数目超过数组大小的时候需要使用realloc函数扩展缓冲区数组。,五 DSP中GEL文件详解,GEL是通用扩展语言(General Extension Language)的英文缩写,GEL是一个大小写敏感但缺少类型检测的解释性语言,只有int类型,在语法上可看作是C语言的一个子集。,GEL文件,GEL 支持以下类型的语句: 函数定义 函数参数 调用 GEL 函数 返回语句 if-else 语句 while or do while语句 GEL 注释 预处理语句,GEL的作用在于扩展CCS Studio的功能,可以
12、用gel来调用一些菜单命令,对DSP的存储器进行初始化配置等,但不是必需的。当希望上电后立刻开启或实现某些功能,那么可以在项目中装载GEL文件(由TI提供或用户自行编写)来实现这个目的。但是建议对于使用仿真器和DSP功能板的仿真环境用户来说,这种GEL语言文件是没必要加入到配置中的。gel语言的重要性在于针对计算机模拟环境的用户,使用gel可以为其准备一个虚拟的DSP仿真环境,但也不是非用不可的。”,GEL文件到底需不需要加载?,GEL文件,合众达自带evmdm6437.gel文件中用到的GEL函数,StartUp( ) /*进行CCS存储器映射,告知目标处理器哪些空间可以访问,哪些不可以访问
13、。*/ Setup_Memory_Map( );OnTargetConnect( )/对处理器进行最小初始化 Setup_Cache( ); /设置缓存L1P,L1D,L2 Setup_Pin_Mux( ); / 设置管脚 Setup_Psc_All_On( ); / 设置psc Setup_PLL0_594_MHz_OscIn( ); / 设置dsp主频DSP 594 MHzCore 1.20V Setup_PLL1_DDR_135_MHz_OscIn();/设置ddr时钟频率 Setup_Aemif_8Bit_Bus( ); / 设置Async-EMIF8-bit bus,GEL文件回调函
14、数,Startup()和OnTargetConnect()函数,对于CCS 2.4或之后的版本,比如3.3版本启动时,如果指定的GEL文件中包含Startup()函数,Startup()函数中不用包括访问目标处理器的代码,目标处理器由回调函数OnTargetConnect()来初始化。,GEL文件回调函数,在加载program/symbol(.out)文件之前该回调函数执行。在该函数中执行另外的目标处理器初始化操作以保证程序可以加载和调试是一个好的选择。例如,我们可以在该函数中初始化外部存储器。,OnPreFileLoaded()函数,OnFileLoaded()函数,该回调函数在加载prog
15、ram/symbol(.out)文件之后执行。可以建立调试源搜索路径(在没有CCS工程文件的时候),设定断点和探针,完成软件的复位和重启。,GEL文件回调函数,OnReset()函数,当目标处理器复位后该函数被调用。如果你需要每次重新启动程序设计了软复位,GEL_Restart()在此处调用。如上是DM642EVM.gel文件中的OnReset()函数。,GEL文件回调函数,OnRestart ()函数,OnHalt()函数,当程序复位时调用该函数。,当CPU停止时调用该函数。还可以通过该回调函数记录变量和寄存器的值送给GEL_TextOut()函数显示出来。,GEL文件回调函数,GEL文件,
16、合众达自带evmdm6437.gel文件中用到的GEL函数,GEL文件存储器映射,1).GEL_MapAdd( address , page , length , readable , writeable) address:存储器起始地址 page:存储器类型 0 表示程序存储器,1 表示数据存储器 length:定义的存储器长度 readable:定义存储器是否可读,1 可读,0 不可读 writeable:定义存储器是否可写,1 可写,0 不可写,作用:CCSStudio存储器映射告诉调试器目标处理器的哪些存储区域可以访问哪些不能访问。CCSStudio存储器映射一般在StartUp()函
17、数中执行。,2).GEL_MapAddStr()GEL_MapAddStr是GEL_MapAdd的增强型。It provides the same readable/writable attributes that can be specified in GEL_MapAdd(). However, it also supports additional parameters for memory access size, a “shared memory” tag, and specification of memory wait states.所以 GEL_MapAddStr()完全可以替
18、代GEL_MapAdd()!,4).可以调用GEL_MapOn() or GEL_MapOff()来打开或关闭存储区映射。当存储区映射关闭时,CCSStudio假定可以访问所有的存储区空间。,5). GEL_MapReset()函数清除所有的存储区映射。没有存储区映射时,缺省设置是所有的存储区空间都不能访问。,GEL文件存储器映射,3).GEL_MapDelete() 函数可以让存储器映射的一部分被隔离开,当存储器部分区域不可用时,使用该函数将其隔离开,这样调试器就不会访问该区域。,GEL文件,合众达自带evmdm6437.gel文件中用到的GEL函数,GEL文件其他函数,GEL_TextOu
19、t() 输出格式化字符串到输出窗口,GEL_TargetTextOut 输出一个目标处理器上的格式化字符串到输出窗口,GEL_CloseWindow 关闭一个输出窗口,GEL_OpenWindow 打开一个输出窗口,C27x_E1_memory_map和 C27x_E3_memory_map没有查到相关资料?,此外,项目添加TI公司提供的GEL文件后往往会在CCS的GEL菜单中出现相关的子菜单,用户可以使用它,主要用于程序的调试控制。GEL文件可以看成你所建项目的“秘书”,可以帮你打打杂,处理一些繁琐的事情。,如何将 GEL 函数加载到 CCS 的 GEL 菜单?,使用关键词!,在没有加载GE
20、L函数之前,CCS的GEL菜单下为空。,GEL文件关键词,a :menuitem和 hotmenu 关键词,添加一级菜单,添加二级子菜单,b :dialog关键,GEL文件关键词,c :slider 关键词主要是创建一个可以改变参数的滑动条,slider param_definition( minVal,maxVal,increment,pageIncre-ment,paramName)参数含义分别为最小值,最大值,步进,页步进和变量名。,GEL文件关键词,水晶头里面有8根有色线,网线的另一头,同样的颜色,同样的颜色顺序连接到交换机或者HUB上。其实,在10M/100M的网络环境中,这8根线里
21、,只有4根线是有用的(接触点面从左往右依次是1,2,3,6),其他都没用。1、2点用于发送数据,3、6点用于接收数据。我们单机之所以无法实现联网,其实就是1、2发出去的数据没有回应消息。而3、6则是收不到任何信号。如若有回应,则就构成了回环网络。,在合众达板子上边测试了“以太网接口”,测试结果显示“ FAIL. error code 12. quitting”表示测试失败,猜想是否出在回环网线问题?不理解自闭环测试方式是什么意思?,关于回环网线,疑惑1?,疑惑1?测试过程,“#define SW_BREAKPOINT asm( ” SWBP 0“ );”中asm( “ SWBP 0” )指令是什么意思?学习TI公司推出的CCS3.3开发环境中文入门指导书的时候,通过Symbol Browser(符号浏览器)查看工程源文件中有“dm6437.c”文件(该文件包含EVMDM6437_init()等函数),但是却找不到,不知为何?,疑惑2?,