第5章 TMS320C54x 软件开发 - PowerPoint PPT Presentation

hasad-grimes
5 tms320c54x n.
Skip this Video
Loading SlideShow in 5 Seconds..
第5章 TMS320C54x 软件开发 PowerPoint Presentation
Download Presentation
第5章 TMS320C54x 软件开发

play fullscreen
1 / 139
Download Presentation
第5章 TMS320C54x 软件开发
109 Views
Download Presentation

第5章 TMS320C54x 软件开发

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. 第5章 TMS320C54x软件开发 • 5.1 软件开发过程及开发工具 • 5.2 公共目标文件格式 • 5.3 常用汇编伪指令 • 5.4 链接器命令文件的编写与使用 • 5.5 汇编语言程序编写方法 • 5.6 TMS320C54x C语言编程 • 5.7 用C语言和汇编语言混合编程

  2. 5.1 软件开发过程及开发工具 1.建立源程序 2.C编译器(C Compiler) 3.汇编器(Assembler) 4.连接器(Linker) 5.调试工具 6.十六进制转换公用程序(Hex Conversion Utility) 返回首页

  3. 图5-1 TMS320C54x DSP软件开发流程(1)

  4. C源文件 汇编 源文件 汇编 源文件 宏库 目标 文件库 运行时 支持库 宏源文件 调试工具 可执行的 COFF文件 存档器 链接器 存档器 汇编器 建库工具 C编译器 TMS320C54x HEX代码 转换工具 EPROM 编程器 绝对地址 列表器 交叉引用 列表器 COFF 目标文件 图5-1 TMS320C54x DSP软件开发流程(2)

  5. C编译器:用来将C/C++语言源程序自动编译为’C54x的汇编语言源程序。  汇编器:用来将汇编语言源文件汇编成机器语言COFF目标文件。  链接器:将汇编生成的、可重新定位的COFF目标模块组合成一个可执行的COFF目标模块。  归档器:允许用户将一组文件(源文件或目标文件)集中为一个文档文件库。  交叉引用列表器:利用目标文件生成一个交叉引用清单,列出链接的源文件中的符号以及它们的定义和引用情况。

  6. . cmd 链接命 令文件 .asm 源文件 .obj 目标文件 .out 输出文件 调试程序 文本编辑器 汇编器 链接器 -o -m -l 十六进制 转换程序 HEX500 . lst 列表文件 . map 存储器 映像文件

  7. 调试工具  软件仿真器:是一种模拟DSP芯片各种功能并在非实时条件下进行软件调试的调试工具,它不需目标硬件支持,只需在计算机上运行。 硬件仿真器:可扩展的开发系统仿真器(XDS510) ,可用来进行系统级的实时集成调试,是进行DSP芯片软硬件开发的最佳工具。  评价模块EVM板:是一种低成本的开发板,可进行DSP芯片评价、性能评估和有限的系统调试。

  8. 表5-1 TMS320C54xV3.50版代码生成工具程序 返回本节

  9. 十六进制转换程序 • 用C/C++语言或汇编语言编写源文件,经C编译器、汇编器生成COFF格式的目标文件,再用链接器进行链接,生成在C54x上可执行的目标代码,然后利用调试工具对可执行的目标代码进行仿真和调试。 • 当调试完成后,通过Hex代码转换工具,将调试后的可执行目标代码转换成EPROM编程器能接受的代码,并将该代码固化到EPROM中或加载到用户的应用系统中,以便DSP目标系统脱离计算机单独运行。

  10. 5.2 公共目标文件格式 • 5.2.1 COFF文件的基本单元——段 • 5.2.2 汇编器对段的处理 • 5.2.3 链接器对段的处理 • 5.2.4 重新定位 • 5.2.5 程序装入 • 5.2.6 COFF文件中的符号 返回首页

  11. 5.2.1 COFF文件的基本单元——段 • 段(sections)是COFF文件中最重要的概念。一个段就是最终在存储器映象中占据连续空间的一个数据或代码块。目标文件中的每一个段都是相互独立的。一般地,COFF目标文件包含3个缺省的段:text段、data段、bss段。 • 段可以分为两大类,即已初始化段和未初始化段。如图5-2所示为目标文件中的段与目标系统中存储器的关系。

  12. 图5-2 目标文件中的段与目标存储器的关系 返回本节

  13. 5.2.2 汇编器对段的处理 1.未初始化段 • 未初始化段主要用来在存储器中保留空间,通常将它们定位到RAM中。这些段在目标文件中没有实际内容,只是保留空间而已。程序可以在运行时利用这些空间建立和存储变量。未初始化段是通过使用.bss和.usect汇编伪指令建立的,两条伪指令的句法分别为: .bss 符号,字数 符号 .usect “段名”,字数

  14. 2.已初始化段 • 已初始化段包含可执行代码或已初始化数据。这些段的内容存储在目标文件中,加载程序时再放到TMS320C54X存储器中。三个用于建立初始化段的伪指令句法分别为: .text [段起点] .data [段起点] .sect “段名”[,段起点]

  15. 3.命名段 • 命名段就是程序员自己定义的段,它与缺省的.text、.data和.bss段一样使用,但与缺省段分开汇编。data段不同的存储器中,将未初始化的变量汇编到与.bss段不同的存储器中。产生命名段的伪指令为: 符号 .usect “段名”,字数 .sect “段名”[,段起点]

  16. 4.子段 子段(Subsections)是大段中的小段。链接器可以像处理段一样处理子段。采用子段可以使存储器图更加紧密。子段的命名句法为: 基段名:子段名 子段也有两种,用.sect命令建立的是已初始化段,用.usect命令建立的是未初始化段。 例如,若要在.text段内建立一个称之为_func的子段,其命令格式: • .sect “.text:_func”

  17. 5.段程序计数器(SPC) • 汇编器为每个段安排一个独立的程序计数器,即段程序计数器(SPC)。SPC表示一个程序代码段或数据段内的当前地址。开始时,汇编器将每个SPC置0,当汇编器将程序代码或数据加到一个段内时,相应的SPC增加。如果汇编器再次遇到相同段名的段,继续汇编至相应的段,且相应的SPC在先前的基础上继续增加。

  18. 段命令应用举例 【例5-1】段命令应用举例。 汇编语言源程序: .data coeff .word 044h,055h,066h .bss buffer,8 prt .word 0456h .text add: LD 0Dh,A aloop:SUB #1,A BC aloop,AGEQ .data ivals .word 0CCh,0DDh,0EEh ;初始化数据段 ;3组数据放入.data段 ;在.bss段保留8个单元 ;0456h放入.data段 ;初始化文本段 ;1字指令 ;2字指令 ;2字指令 共计5个字 ;初始化数据段 ;3组数据放入.data段

  19. 段命令应用举例 汇编语言源程序: ;建立newvars命名段,保留2个单元 ;在newvars段保留8个单元 ;初始化文本段 ;1字指令 ;2字指令 ;2字指令 var2 .usect “newvars”,2 inbuf .usect “newvars”,8 .text mpy: LD 0Ah,B mloop: MPY #0Ah,B BC mloop,BNOV .sect “vectors” .word 044h,088h 共计5个字 ;建立vectors命名段 ;2组数据放入vectors命名段

  20. 段命令应用举例 经汇编后,得列表文件(部分): 2 ********************************** 3** 汇编一个初始化表到.data段 ** 4********************************** 50000 .data 600000044 coeff .word 044h,055h,066h 0001 0055 0002 0066 7 ********************************** 8 ** 在.bss段中为变量保留空间 ** 9 ********************************** 100000 .bss buffer,8 11 ********************************** 12 ** 仍然在.data 段中 ** 13 ********************************** 140003 0456 prt .word 0456h

  21. 段命令应用举例 15 ********************************** 16 ** 汇编代码到.text段 ** 17 ********************************** 180000 .text 190000100d add: LD 0Dh,A 200001f010 aloop: SUB #1, A 00020001 210003 f842BC aloop,AGEQ 00040001’ 22********************************** 23** 汇编另一个初始化表到.data 段 ** 24 ********************************** 250004.data 26000400cc ivals .word 0CCh,0DDh,0EEh 0005 00dd 000600ee 27 ********************************** 28 ** 为更多的变量定义另一个段 ** 29 ********************************** 300000 var2 .usect “newvars”,2 31 0001inbuf .usect “newvars”,8

  22. 段命令应用举例 32 **************************************** 33 ** 汇编更多代码到.text段 ** 34 **************************************** 350005.text 360005 110ampy: LD 0Ah,B 37 0006f166 mloop MPY #0Ah,B 0007000a 380008 f868 BC mloop,BNOV 00090006’ 39 **************************************** 40 ** 为中断向量.vectors定义一个自定义段 ** 41 **************************************** 420000.sect “vectors” 43 00000044.word 044h,088h 00010088 源程序的行号 段程序 计数器 目标 代码 汇编语言 源程序

  23. 段命令应用举例 汇编语言源程序经过汇编后,共建立了5个段: ●.text段——文本段,段内有10个字可执行 的程序代码。 ●.data段——已初始化的数据段,段内有7 个字的数据。 ●vectors段——用.sect命令生成的命名段, 段内有2个字的初始化数据。 ●.bss段——未初始化的数据段,在存储器中 为变量保留8个存储单元。 ●newvars段——用.usect命令建立的命名段, 为变量保留10个存储单元。

  24. 段命令应用举例 经汇编后,得列表文件(部分): 2 ******************************* 3** 汇编一个初始化表到.data段 ** 4******************************* 50000 .data 600000044 coeff .word 044h,055h,066h 0001 0055 0002 0066 7 ******************************* 8 ** 在.bss段中为变量保留空间 ** 9 ******************************* 100000 .bss buffer,8 11 ******************************* 12 ** 仍然在.data 段中 ** 13 ******************************* 140003 0456 prt .word 0456h 5 0000 .data 6 0000 0044 coeff .word 044h,055h,066h .data 6 0044 6 0055 6 0066 0456 14 10 0000 .bss buffer,8 .bss 10 没有数据 保留8个字 14 0003 0456 prt .word 0456h

  25. 段命令应用举例 15 ******************************** 16 ** 汇编代码到.text段 ** 17 ******************************** 180000 .text 190000100d add: LD 0Dh,A 200001f010 aloop: SUB #1, A 00020001 210003 f842BC aloop,AGEQ 00040001’ 22********************************** 23** 汇编另一个初始化表到.data 段 ** 24 ********************************** 250004.data 26000400cc ivals .word 0CCh,0DDh,0EEh 0005 00dd 000600ee 27 ******************************** 28** 为更多的变量定义另一个段 ** 29 ******************************** 300000 var2 .usect “newvars”,2 310001inbuf .usect “newvars”,8 .text 19 100d 20 f010 20 0001 18 0000 .text 21 f842 21 19 0000 100d add: LD 0Dh,A 0001 20 0001 f010 aloop: SUB #1, A 21 0003 f842 BC aloop,AGEQ .data 26 00cc 25 0004 .data 26 00dd 26 0004 00cc ivals .word 0CCh,0DDh,0EEh 00ee 26 30 0000 var2 .usect “newvars”,2 newvars 30 保留2个字 31 0001 inbuf .usect “newvars”,8 31 保留8个字

  26. 段命令应用举例 32 ********************************* 33** 汇编更多代码到.text段 ** 34 ********************************* 350005.text 360005 110ampy: LD 0Ah,B 37 0006f166 mloop MPY #0Ah,B 0007000a 380008 f868 BC mloop,BNOV 00090006’ 39 **************************************** 40 ** 为中断向量.vectors定义一个自定义段 ** 41 **************************************** 420000.sect “vectors” 43 00000044.word 044h,088h 00010088 .text 35 0005 .text 36 0005 110a mpy: LD 0Ah,B 36 110a 37 f168 37 0006 f166 mloop MPY #0Ah,B 37 000a 38 f868 38 0006 38 0008 f868 BC mloop,BNOV 42 0000 .sect “vectors” vectors 43 0044 43 0000 0044 .word 044h,088h 43 0088

  27. 5.2.3链接器对段的处理 链接器是开发’C54x器件必不可少的开发工具之一,它对段处理时有2个主要任务: ①将一个或多个COFF目标文件(.obj文件)中的各种段作为链接器的输入段,经链接后在一个执行的COFF输出模块中建立各个输出段; ② 在程序装入时对其重新定位,为各个输出段选定存储器地址。

  28. 链接器有2条伪指令支持上述任务: ●MEMORY伪指令——用来定义目标系统的存储器配置空间,包括对存储器各部分命名,以及规定它们的起始地址和长度。 ●SECTIONS伪指令——用来指定链接器将输入段组合成输出段方式,以及输出段在存储器中的位置,也可用于指定子段。 若未使用伪指令,则链接器将使用目标处理器默认的方法将段放入存储空间。

  29. 一、默认的存储器分配 链接器可对多个目标文件进行链接。若链接文件中不使用MEMORY和SECTIONS命令,则为默认方式。 每个目标文件都有.text,.data、.bss段和命名段。若采用默认链接,链接器将对多个目标文件中的各个段进行组合,形成各自的对应段,并将各个段配置到所指定的存储器中,形成可执行的目标模块。 在默认的方式下,链接器将从存储器的0080h开始,对组合后的各段进行存储器配置。

  30. 默认的存储器分配方法: ① 将所有.text段组合在一起,形成一个.text段,并分配到程序存储器中; ② 将多个目标文件中的.data段组合在一起,分配到紧接着.text段的程序存储空间中; ③ 将.bss段组合,配置到数据存储器中; ④ 组合命名段。初始化的命名段按顺序分配到紧随.data段的程序存储器,而未初始化命名段将被配置到紧随.bss段的数据存储器中。

  31. 默认的存储器分配过程: .text1 没有配置 .text .text2 .data1 .data .data2 .bss1 .bss table_1 .bss2 u_vars1 table table_2 u_vars1 u_vars2 FFT FFT 没有使用 没有使用 没有配置

  32. 二、段放入存储器空间 若不希望链接器将所有的.text段结合在一起形成单个的.text段,就不能采用默认的方式。 由于DSP硬件系统中可能配置多种类型的存储器,若要把某一段分配到特定类型的存储器中,或将命名段配置特定的地址,则需采用MEMORY和SECTIONS伪指令来配置。 若不采用默认的方式,通常需要建立一个链接命令文件,在命令文件中用MEMORY和SECTIONS伪指令定义存储器和配置段地址。

  33. 5.2.4链接器对程序的重新定位 1.链接器重新定位 汇编器对每个段汇编时都是从0地址开始,而所有需要重新定位的符号(标号)在段内都是相对于0地址的。事实上,所有段都不可能从存储器中0地址单元开始,因此链接器必须对各个段进行重新定位。 重新定位的方法: 将各个段配置到存储器中,使每个段都有一个 合适的起始地址; 将符号变量调整到相对于新的段地址的位置; 将引用调整到重新定位后的符号,这些符号 反映了调整后的新符号值。

  34. 1.链接器重新定位 【例4.3.2】一段采用助记符指令编写的程序,经汇编后得列表文件如下: 汇编器在需要引用重新定位的符号处都留了一个重定位入口。链接器在对符号重新定位时,利用这些入口修正对符号的引用值。 1. ref X 2. ref Z 30000. text 40000F073B Y;产生一个重定位入口 00010006’ 50002F073B Z;产生一个重定位入口 00030000! 60004F020LD #X,A;产生一个重定位入口 00050000! 70006F7E0Y: RESET

  35. 程序中有三个符号: X、Z——是在另一个模块中定义的; Y——在.text段中定义的。 当程序汇编时,X、Z的值为0——未定义的外部符号 Y的值为6——相对于.text段地址0定义 汇编器形成了两个重定位入口: X和Z:在.text段中为一次外部引用,用符号!表示; Y:是一次内部引用,用符号’表示。 假设链接时,X重新定位在地址7100h .text段起始地址重新定位在7200h

  36. 链接器利用两个重定位入口,对目标文件中的两次引用进行修正:链接器利用两个重定位入口,对目标文件中的两次引用进行修正: f073B Y 0006’ f020LD #X,A 0000! 变成f073 7206’ 变成f020 7100!

  37. 2.运行时重新定位 在实际运行中,有时需要将代码装入存储器的一个地方,而在另一个地方运行。 如:一些关键的执行代码必须装在系统的ROM中,但运行时希望在较快的RAM中进行。 利用SECTIONS伪指令选项可让链接器对其定位2次,其方法: ① 使用装入关键字设置装入地址; ② 使用运行关键字设置它的运行地址。

  38. 装入地址确定段的原始数据或代码装入的位置,而任何对段的使用(例如其中的标号),则参考它的运行地址。在应用中必须将该段从装入地址复制到运行地址。装入地址确定段的原始数据或代码装入的位置,而任何对段的使用(例如其中的标号),则参考它的运行地址。在应用中必须将该段从装入地址复制到运行地址。 如果只为段提供了一次定位(装入或运行),则该段将只定位一次,并且装入和运行地址相同。如果提供了2个地址,则段将被自动定位。

  39. 5.2.5 程序装入 可以采用以下方法装入程序: 链接器产生可执行的COFF目标文件。可执行的目标文件模块与链接器输入的目标文件具有相同的COFF格式。为了运行程序,在可执行模块中的数据必须传输或装入目标系统存储器中。  使用调试工具转入程序 ’C54x的调试工具包括软件模拟器,XDS仿真器和集成系统CCS。它们都具有内部的装入器,调用装入器的LOAD命令,装入器将程序复制到目标系统的存储器中。  采用Hex转换工具转入程序 可以使用转换工具Hex500,将可执行COFF目标模块转换成几种其他目标格式文件,然后将转换后的文件通过编程器将程序装(烧)进EPROM。

  40. 5.2.6COFF文件中的符号 COFF文件中有一个符号表,主要用来存储程序中有关符号的信息。链接器在执行程序定位时,要使用符号表提供的信息,而调试工具也要使用该表来提供符号调试。 1.外部符号 是指在一个模块中定义、而在另一个模块中引用的符号。它可以用伪指令.def、.ref或.global来定义。 ●.def在当前模块中定义,并可在别的模块中使用的符号; ●.ref 在当前模块中使用,但在别的模块中定义的符号; ●.global可以是上面的任何一种情况。

  41. 【例5-3】说明代码段中外部符号的定义。 x: ADD #56h,A B y .def x .ref y ;定义x ;引用y ;x在此模块中定义,可为别 的模块引用 ;y在这里引用,它在别的模 块中定义

  42. 2.符号表 每当遇到一个外部符号,无论是定义的还是引用的,汇编器都将在符号表中产生一个条目。 汇编器还产生一个指到每段的专门符号,链接器使用这些符号将其他引用符号重新定位。

  43. 5.3 常用汇编伪指令 表5-2 常用的汇编伪指令 返回首页

  44. 1.段定义伪指令 为便于链接器将程序、数据分段定位于指定的(物理存在的)存储器空间,并将不同的obj文件链接起来。段的使用非常灵活,但常用以下约定: .text—此段存放程序代码。 .data—此段存放初始化了的数据。 .bss—此段存入未初始化的变量。 .sect‘名称’—定义一个有名段,放初始化了的数 据或程序代码。

  45. 2.条件汇编伪指令 • .if、.elseif、.else、.endif伪指令告诉汇编器按照表达式的计算结果对代码块进行条件汇编。 • .if expression—标志条件块的开始,仅当条件为真(expression的值非0即为真)时汇编代码。 • .elseif expression—标志若.if条件为假,而.elseif条件为真时要汇编代码块。 • .else—标志若.if条件为假时要汇编代码块。 • .endif—标志条件块的结束,并终止该条件代码块。

  46. 3.引用其他文件的伪指令 • .copy “文件名”— 将指定文件复制到当前位置,其内容可以是程序、数据、符号定义等。 • .include “文件名”—与.copy类似。只是被copy的文件名会出现在汇编时生成的列表中。 如: .copy “d:\dsp\file.asm”

  47. .def 符号名 — 在当前文件中定义一个符号,可以被其他文件使用。 • .ref 符号名 — 在其他文件中定义,可以在本文件中使用的符号。 • .global 符号名 — 其作用相当于.def、.ref效果之和。 • .def 符号 [,…,符号] • .global 符号 [,…,符号] • .ref 符号 [,…,符号] • 如:.def new1,new2

  48. 4.初始化常数伪指令 • .word 数1,数2—指定一个或多个16位带符号整数(十六进制)连续放置到存储器中。 • .int 数1,数2—指定一个或多个16位无符号整数(十六进制)连续放置到存储器中。 • .float 数1,数2—指定的各浮点数连续放置到存储器中(从当前段指针开始)。 • .space n—以位为单位,空出n位存储空间。 • .string “字符串” [,…,“字符串”]—初始化一个或多个字符串。把8位字符从一个或多个字符串放进当前段。

  49. 【例5-4】比较.word ,.int,. float和.string伪指令。 源程序: .word0CCCh .int0DDDDh .float1.99999 .string“help” .word:将一个或多个16位值放入当前段的连续字中。 .int:将一个或多个16位值放入当前段的连续的字中。 .float:初始化单精度(32位) 浮点数,并保存在当前段的两个连续的字中。 .string:将一个或多个字符串中的8位字符放入当前段中。

  50. 列表文件: 1 0000000ccc.word 0CCCh 2 000001dddd.int 0DDDDh 3 0000023fff.float 1.99999 000003 ffac 8 0000040068.string “help” 0000050065 000006006c 0000070070 .float:自动对准最近长字边界