admin 管理员组文章数量: 887021
2024年1月24日发(作者:有名的公司)
第5章 嵌入式代码的快速生成
利用RTW-EC(Real-Time Workshop Embedded Coder)等工具为用户算法自动生成嵌入式代码,是一种高效、实用的方法,目前国内外各大公司在进行新产品开发时已广泛采用。其核心思想是让工程师把主要精力集中于算法的研究上,把枯燥、困难的代码编写工作留给计算机去自动完成,这样可以大大缩短产品的开发周期,降低市场风险。本章主要以TI DSP为例讲述嵌入式代码的快速生成方法。它的工作流程如图5.1.1所示:
Model and Simulate in Floating-Point and Fixed-PointModel Advisor and V&V for ModelGenerate embeddable C-code from Simulink and/or Embedded MATLABRapidly Prototype and Implement on TI processors and boardsMATLABSimulinkStateflowEmbedded IDE Link For Use with
TI’s Code Composer StudioC/ASM CodeCompile&LinkDown
loadDebugTexas Instruments Code
Composer Studio
Environment
图5.1.1 TI DSP代码快速生成的工作流程
本章主要内容包括:
CCS介绍
利用RTWEC生成DSP的目标代码
MATLAB与CCS的交互式开发
应用实例
5.1 CCS介绍
CCS(Code Composer Studio)代码调试器是一种针对TI产品的交互式集成开发环境IDE。它提供了环境配置、源文件编辑、程序调试、跟踪和分析等工具。CCS的功能十分强大,它集成了代码的编辑、编译、链接和调试等诸多功能,而且支持C/C++和汇编的混合编程。
CCS的应用程序主要完成系统的软件开发与调试,能将汇编语言和C语言程序编译链接生成COFF(公共目标文件)格式的可执行文件,并将程序下载到目标DSP上运行。
进行CCS开发的代码生成流程图如图5.1.2所示,源代码文件通过编译自动打开反汇编窗口(参看5.1.1节)。链接器根据目标系统的存储空间信息能够将COFF目标文件链接成可执行文件(.out),目标系统的存储空间信息是在链接器命令文件(.cmd)中配置的(参看
5.1.2节)。
由于3.3版本的CCS断点中隐含探针的功能,因此工具栏上不再有探针的图标。为了解开一部分读者对CCS3.3探针的疑惑,将在5.1.3节着重介绍探针的设置。
C或C/C++源文件C/C++编译器汇编优化器:仅用于C6000语法分析器优化器(可选)预汇编器代码生成器链接器选项(-z)汇编源.asm文件链接器汇编器可执行COFF文件.out文件COFF目标(.obj)文件
图5.1.2 代码生成流程图
5.1.1 反汇编窗口
可通过选择View → Disassembly,或点击调试工具栏的View Disassembly图标来打开反汇编窗口。把可执行代码加载到目标板或Simulator中时,CCS IDE会自动打开反汇编窗口,反汇编窗中显示调试所需的反汇编指令及符号信息。反汇编是汇编的逆过程,是将存储器的内容用汇编语言代码显示出来,符号信息包括目标板上表示地址或值的字符或字符串。
对每一条反汇编指令,反汇编窗同时显示该指令所在的存储器地址及其对应的机器代码,用一个黄色箭头指示当前程序计数器PC的位置(如图5.1.3所示)。当用stepping命令单步执行程序时,PC指针会指向当前执行指令的前一行。
图5.1.3 反汇编窗口
5.1.2 链接命令文件
CCS的工程文件需包含CMD文件,即链接命令文件,用来配置目标系统的存储空间分配,并为各段指定地址。常用的命令标识符有MEMORY和SECTIONS这两个伪指令,利用这些标示符可为各段指定存储区域,组合各目标文件中的段,并在链接时定义或重新定义全局符号。
CMD文件是ASCII文件,包含以下内容:
①输入文件名,可以是目标文件、库文件或其他命令文件;
②链接器选项;
③MEMORY和SECTIONS命令,MEMORY用于指定目标存储器的配置,SECTIONS用于指定段的地址;
④赋值语句,用于定义全局符号,并赋值。
MEMORY命令格式
MEMORY
{
[PAGE 0]: name 1[(attr)]: origin=constant, length=constant
…
[PAGE n]: name n[(attr)]: origin=constant, length=constant
}
其中,PAGE是可选项,用于指定存储空间页面,通常PAGE 0用于程序存储器,PAGE
1用于数据存储器,默认值为PAGE 0;name为一段存储空间的名称;attr指定段存储空间的属性,有4种选项可选,R表示可读,W表示可写,X表示可以存放执行代码,I表示可以被初始化,默认值具有4种属性;origin表示该段存储空间的起始地址,length表示该段存储空间的长度。
SECTIONS命令格式
SECTIONS
{
name:[property, property, property,…]
name:[property, property, property,…]
…
}
其中,name表示段的名称,是在程序中定义的;property为该段的属性,包括段的内容及在存储空间中的位置。
5.1.3 探针的设置
利用断点可以在指定位置提取/注入数据。断点可以设置在程序的任何位置,当程序运行到断点处时,与断点相关的事件将会被触发,当事件结束后程序会继续执行。
具体设置:
①在要提取/注入数据的代码行单击右键,选择“Toggle Software Breakpoint”,设置软件断点。
②选择Debug → Breakpoint,列出所设置的断点列表,在列表中选取相应的断点,右键选择Property Window,设置相应的属性,如放置的地址、输入读取的数据个数和关联的数据文件(*.dat),数据为输入时Action设置为Read Data from File,为输出时设置为Write
Data to File。
5.1.4 CCS的使用
在“Setup CCStudio v3.3”中配置CCS的工作环境,“CCStudio v3.3”为CCS的应用程序。
CCS的配置文件是用来定义DSP芯片和目标板类型的,为了使CCS能工作在不同的硬件或仿真目标板上,必须为CCS系统配置相应的配置文件。配置步骤:
双击桌面上的Setup CCStudio v3.3图标,弹出如图5.1.4所示的界面。可在Available
Factory Boards列表中选择与目标系统相匹配的配置,将它添加到My System中并保存设置。
图5.1.4 配置CCS目标板
下面通过一个例子介绍CCS软件的使用。
先设置CCS在C6416软仿真环境下运行,选择小端模式(little Endianness)的处理器,再启动CCS的应用程序,选择菜单Debug → Reset CPU。
在CCS的安装目录下创建一个新的用户目录CCSrootMyProjectsVolume (CCSroot为CCS的安装目录) ,把CCSroottutorialsim64xxvolume1目录下的所有文件(除去工程文件.pjt)拷贝到CCSrootMyProjectsVolume目录下。
(1)创建新的工程文件。选择菜单“Project”的“New”项,弹出如图5.1.5所示的对话框,在Project栏输入要创建的工程名volume,该工程为一空工程。
图5.1.5 新建工程的对话框
(2)向工程中添加文件。选择菜单“Project”的“Add Files to Project”项,添加volume.c、、、、volume.h文件到volume工程中,再添加库文件到volume工程中,完成工程文件的建立。
(3)选择菜单“Project”的“Build Options…”项。在“Build Options for ” 对话框中“Compiler”属性页的“Basic”栏中修改“Target Version”项的内容为“C64xx(-mv6400)”(如图5.1.6),设置生成64xx的程序代码。
图5.1.6 Build Options对话框
选择“Linker”属性页的“Basic”栏,修改用户堆栈(-heap、-stack)的大小为1024个字,如图5.1.7所示。
图5.1.7 链接器属性对话框
(4)编译链接工程。选择菜单“Project”的“Rebuild All”项,或单击工具条中的按钮;注意编译过程中CCS主窗口下部的“Build”提示窗中显示编译信息,最后将给出错误和警告的统计数,如图5.1.8所示。
图5.1.8 编译结果
这个程序是一个采集信号并处理输出的程序,程序的主循环中调用函数dataIO来读写数据,processing函数处理数据,整个系统可以完成将输入的数据扩大gain倍后再输出的功能。此例用读文件的方式获得输入的数据,processing子程序中首先将输入缓冲区的数据进行放大处理,即乘以系数gain(取值为2),然后再放入输出缓冲区中。
而文件定义程序所放置的位置,可用存储器给定起始地址和长度(区域地址空间不允许重叠),然后指定经编译器编译后产生的各模块存放到哪个区域。
图5.1.9 CMD文件
(5) 载入.out文件。执行File → Load Program,在随后打开的对话框中选择刚刚建立的文件。
(6) 断点调试。先设置断点,双击volume.c 激活这个文件,移动光标到main()行上,单击鼠标右键选择Toggle Software Breakpoint设置断点(双击此行左边的灰色控制条也可以设置或删除断点标记)。选择Debug->Run或按F5运行程序,程序会自动停在main()函数上。
①按F10执行到processing ()函数。
②再按F11,程序将转到processing函数中运行。
③此时,为了返回主函数,按shift-F11完成processing函数的执行。
④再次执行到processing一行,按F10执行程序,此时不进入子程序的执行。
(7) 使用观察窗口。选择View->Watch Window打开观察窗口,在volume.c中,用鼠标双击一个变量(如size),再单击鼠标右键,选择“Quick Watch”,CCS将打开Quick Watch窗口并显示选中的变量;或者在volume.c 中,选中变量size,单击鼠标右键,选择 “Add to
Watch Window”,CCS将把变量添加到观察窗口中并显示选中的变量值。在观察窗口中双击变量,则弹出修改变量窗口。此时,可以在这个窗口中改变变量的值。
① 把str变量加到观察窗口中,点击变量左边的”+”,观察窗口可以展开结构变量,并且显示结构变量的每个元素的值。
② 把size变量加到观察窗口中,执行程序进入main函数,此时size变量超出了作用范围,如图5.1.10所示。
图5.1.10 Watch Window显示窗口
可以利用Call Stack窗口察看在其他函数中的变量:选择菜单View->Call Stack打开堆栈窗口,图5.1.11显示了processing函数中的变量值。
图5.1.11 Call Stack窗口
(8)数据输入输出。此例中断点触发的事件是:将PC机存储的数据文件中的一段数据加载到DSP的缓冲区中。当程序运行到processing()时,读取已存储的数据文件,在程序行processing(input, output)上单击右键,选择“Toggle Software Breakpoint”,设置软件断点。选择Debug → Breakpoint,列出所设置的断点列表,在列表中选取相应的断点,右键选择Property Window,设置相应的属性,如放置的地址、输入读取的数据个数和关联的数据文件(),数据为输入时Action设置为Read Data
from File,如图5.1.12所示。
图5.1.12 断点属性设置
(9)图形显示。选择View → Graph → Time/Frequency,在弹出的对话框中按图5.1.13所示设置。左边曲线为输入数据(inp_buffer缓冲区中的数据),右曲线为输出数据(out_buffer缓冲区中的数据),该程序中volume定义为2,因此输出数据应该为输入数据的2倍,从实验结果来看输出正好是输入的2倍。如图5.1.14所示:
图5.1.13 图形属性设置窗口
图5.1.14 输入输出信号图
5.2 利用RTW-EC生成DSP目标代码
Embedded IDE Link可将MATLAB与CCS进行无缝连接。用户可以利用MATLAB脚本和Simulink模型在TI系列DSP上调试、验证自动生成的嵌入式代码。利用RTW-EC等工具,从模型生成实时C代码,通过 For Use with TI‟s Code Composer Studio自动调用CCS开发工具来编译链接生成的C代码,并自动下载到TI的目标板上执行生成的代码。主要工作流程如图5.2.1所示。
Simulink and Real-Time WorkshopEmbedded IDE LinkTarget Support Package概念Third-Party IDEEvaluation or Custom Board实现
图5.2.1 Embedded IDE Link工作流程
5.2.1 RTW自动生成代码的过程
利用RTW(Real-Time Workshop)来生成实时代码的过程如图5.2.2所示,分成四个阶段:
①用户建立MATLAB/Simulink/Stateflow模型。RTW读取模型文件并对其进行编译,形成描述模型的文件,该文件以ASCII码的形式进行存储;
②TLC 目标语言编译器读取文件中的信息。将模型转化成源代码。TLC(Target Language Compiler)文件有两种形式,系统TLC文件和模块TLC文件,前者控制整个模型的代码生成,不同的目标使用不同的系统目标文,比如一般实时目标使用,嵌入式实时目标使用 ,而模块TLC文件仅针对某一模块,决定某一模块对应生成什么的代码。
③生成指定目标的代码。RTW代码生成器需要makefile模板,该文件指定合适的C或C++编译器及编译过程中的编译器选项,通过代码生成器将makefile模板文件生成目标makefile文件(),指导程序编译和链接模型中生成的源代码,主程序等。
④连接开发目标程序所需的环境。建立运行时接口支持库,将模型生成的代码编译成在目标系统上直接运行的可执行文件。
MATLAB/Simulink/l-Time WorkshopTLC程序:系统目标文件模块目标文件inlined S-function目标文件Target Language
Compiler函数文件运行时接口支持文件Real-Time
Workshop get Language
图5.2.2 生成实时代码的过程
通过TLC生成S-function代码,可以将用户手写代码嵌入到生成代码中。通过TLC生
成的代码是高度优化的,注释完整,并且能够从任何包含线性的、非线性的、连续的、离散的或混合模块的模型生成代码,除了调用M文件编写的不符合Embedded MATLAB子集的函数模块和S-函数模块外,其他的模块都能自动转换成代码。
而利用RTW-EC代码生成工具,从MATLAB/Simulink/Stateflow用户模型中所产生的代码,是针对嵌入式器件生成的实时代码,其代码长度短,执行效率高。
5.2.2 TI DSP原装板的实时代码生成
用户模型生成实时代码的步骤:
(1)建立实时模型,模型中包含有目标处理器板模块,并在CCS系统配置中选择相应的处理器进行仿真;
(2)设置仿真参数和Real-Time Workshop Embedded Coder;
(3)编译实时模型。
仿真参数的设置:
(1)在模型工具栏中,选择Simulation –> Configuration Parameters,打开配置参数对话框,点击对话框的Solver面板,设置下面几项参数:
① Start time:0.0;
② Stop time:inf;
③ Type:Fixed-step;
④ Soler:discrete(no continuous states)。
图5.2.3 Solver面板
(2)点击对话框的Optimization面板,选中Inline parameters和Inline invariant signals复选框(其余为默认设置)。
Optimization面板各个子区域的作用如下:
表5.2.1 Optimization面板子区域说明
区域
Simulation and code generation
作用
从代码中删除未使用的部分和控制临时变量的创建
减少多个计算变成单任务时和重Signals 复使用临时变量时创建的临时变量的数目
控制哪些信号有明确的初始化代码
溢出或除数为零时允许或禁止保护代码
Data initialization
Integer and fixed-point
图5.2.4 Optimization面板
表5.2.2 Optimization面板选项说明
选项
Signal storage reuse
意义
Real-Time Workshop代码生成器在存储空间重用时存储信号。未选中时,所有模块的输出为全局变量,增加了RAM和ROM的利用率。
Inline parameters
降低RAM利用率,因为不在全局参数结构中声明参数
Enable local block outputs
Reuse block outputs
Inline invariant signals
声明模块信号是局部变量而不是全局变量
减少缓存局部变量的堆栈空间
不为具有固定值的采样时间的模块产生代码
Eliminate superfluous local 减少模块输出的中间结果的计算,以及这些结果在variables (Expression folding) 临时缓冲区的存储
Minimize data copies between
local and global variables
Loop unrolling threshold
Use memcpy for
重用已存在的全局变量来存储临时结果
设置适当的值,即循环展开门限值
如果目标环境支持memcpy函数,而且用信号向量vector 来传输数据时,选中则在生成代码时调用memcpy函数来替代for循环以加速向量分配的执行,还需设置适当的Memcpy threshold (bytes)值。
assignment
(3)点击对话框的Hardware Implementation面板,如图5.2.5所示,可设置硬件属性。
Embedded Hardware子面板描述用到的嵌入式目标硬件和编译器,该信息影响仿真和生成代码的过程。
Emulation Hardware子面板描述用到的仿真器目标硬件和编译器,该信息只影响生成代码的过程。
图5.2.5 Hardware Implementation面板
也可以为包含其他厂商设备的模型生成实时代码,只需在该面板选择相应的设备类型即可。图5.2.6列出了几种常用的厂商的设备类型,即TI、FPGA、ARM和单片机的设备类型。例如选择FPGA设备,则同时要设置其仿真器属性,如图5.2.7所示。
图5.2.6 几种常用厂商的设备类型
图5.2.7 FPGA设备属性设置
(4)点击对话框的Real-Time Workshop选项面板,在此面板中设置参数:
① 点击Browse按钮打开System target file browser(如图5.2.8所示),用户可以在列表中选择目标文件,当用户选择好系统目标文件,Real-Time Workshop会自动设置Template makefile和Make command选项。
如果使用的不是browser中的目标文件,则在System target file栏输入用户自定义系统目标文件名,并自己设置Template makefile和Make command选项,如图5.2.9所示。
用Real-Time Workshop生成实时代码时,设置System target file为ccslink_;使用Real-Time Workshop Embedded Coder生成产品级代码时,设置System target file为ccslink_。
图5.2.8 tlc文件列表
图5.2.9 Real-Time Workshop选项面板
② 在TLC options栏可输入TLC命令选项,选项如下:
表5.2.3 TLC命令选项
-Ipath
-m[N|a]
指定查找*.tlc文件的路径
报告错误的最大个数N,默认值为N=5,如
果要报告所有的错误,则命令为-ma
-d[g|n|o]
-aRTWCAPI
-aRTWCAPISignals
-aRTWCAPIParams
-aVariable=val
③ 通过修改Comments面板的参数来设置在生成的代码中插入注释;
④ 设置Custom Code面板选项向相应的目标集成自定义代码,详见3.8节的介绍;
⑤ 设置Debug面板(图5.2.10),在为自定义目标、集成已存在的代码或开发新的模块写TLC代码时设置debug参数很有用;
指定调试模式(generate,normal或off),默认值为off,当指定为-dg时,会为每个用户的TLC文件创建一个.log文件
-aRTWCAPI=1为信号和参数生成API
-aRTWCAPISignals=1仅为信号生成API
-aRTWCAPIParams=1仅为参数生成API
等价于TLC指令:%assign Variable = val,声明TLC变量或对变量赋值
图5.2.10 Debug面板设置
表5.2.3 Debug面板选项
项目
Verbose build
Retain .rtw file
Profile TLC
意义
在MATLAB命令窗口中显示生成代码的过程信息
在编译完成时阻止从编译目录下删除文件
在代码生成过程中用TLC分析器分析TLC代码的执行效率并生成HTML格式的报告
Start TLC debugger when
在生成代码过程中启动TLC调试器
generating code
Start TLC coverage when
生成包含统计数据的报告
generating code
Enable TLC assertion
用户提供的TLC文件包含%assert指令时值为FALSE则暂停编译
⑥ 设置Interface面板(图5.2.11,System target file为ccslink_时),可以决定在运行时使用的数学函数库;
图5.2.11 Interface面板设置
Target function library指定在生成代码时使用的特定目标数学库,在Target function
library中选择C89/C90(ANSI)使用ANSI C库函数集,如果编译器支持ISO C数学扩展,选择C99(ISO)能生成更有效的代码。
Utility function generation指定Real-Time Workshop代码生成器放置地点和其他程序代码的位置,选择Shared location,则代码放置在工作目录下的slprj目录下,可用来编译参考目标模型;选择Auto,则当模型包含Model模块时,代码放置在slprj/target/_sharedutils目录下,当模型不包含Model模块时,代码放置在编译目录下。
MAT-file variable name modifier指定在MAT-files记录数据时修改变量名,以区分Real-Time Workshop和Simulink应用中记录的数据,可添加前缀rt_或后缀_rt。
Interface指定在生成代码时包含的API,可选择项为None,C-API,External mode或ASAP2。
⑦ Embedded IDE Link选项(图5.2.12)
Build action:选择Build_and_execute;
Interrupt overrun notification method:选择None。
图5.2.12 Embedded IDE Link CC子面板
Build action:指定当用户单击Build按钮时,Real-Time Workshop所执行的操作。有四种操作方式供选择:
表5.2.4 工程建立操作选项
Real-Time Workshop会启动CCS IDE并创建一个新的工程,该工程包含模型编译过程中生成的文件。模型编译过Create_Project 程中生成了modelname.c,,等文件,这些文件存于MATLAB工作目录下的modelname_c6000_rtw文件夹内。
Real-Time Workshop生成一个归档模型库,选择此项,用户可以在模型引用时调用这个库
编译链接可执行COFF文件,但并不把该文件加载到目标DSP中
编译链接可执行COFF文件,把该文件加载到目标DSP中并运行生成的代码
Archive_library
Build
Build_and_execute
Interrupt overrun notification method:溢出通知方式,目标处理器溢出时有下列三种选项:
表5.2.5 处理器溢出处理选项
None 在运行模型时忽略遇到的溢出情况
Print_message
Call_custom_function
当DSP遇到溢出时,打印信息至标准输出设备
通过调用在Interrupt overrun notification
function中指定的自定义函数来响应溢出情况
System stack size(MAUs):处理器为系统堆栈分配的内存,默认值为8192,最小值为0,用户可根据实际情况修改。
Maximum time to complete IDE operations (s):指定等待IDE函数的时间,默认值为10,最小值为1,用户可根据实际情况修改。
5.2.3 代码验证
本节主要介绍通过软件在环测试和处理器在环测试进行模型验证。
1. 软件在环测试
软件在环测试是在主机上对仿真中生成的函数或手写代码的评估。当软件组件包含需要在目标平台上执行的生成代码和手写代码的组合时,应该考虑进行软件在环测试,并且它也验证图形化模型中现有算法的重用问题,完成对模型设计的验证。
Real-Time Workshop Embedded Coder软件为子系统的代码验证提供了软件在环测试(Software-in-the-Loop,SIL),当主机与目标平台间的处理器字长不同时(如32-bit主机与16-bit目标机),有两种方法设置Simulink模型参数使能在MATLAB主机上用SIL仿真目标。
①在参数设置对话框中的Hardware Implementation面板中使能并选中Emulation
hardware选项。
②在参数设置对话框中的Interface面板中选中Enable portable word sizes选项。
如果要保证在MATLAB主机上运行的仿真结果和目标应用系统中执行的生成代码的结果中整数或定点操作的表达式位真时,应选择hardware emulation。
注意:在SIL测试后,Hardware Implementation面板中Emulation hardware选项应选择None。
如果要在MATLAB主机上和目标应用系统中进行SIL测试不需要修改就能编译的代码,则应选择portable word sizes。此时,生成的代码包含额外的处理宏,所以第一次在MATLAB主机上编译时,首先要使用编译选项-DPORTABLE_WORDSIZES,然后在目标平台上编译时忽略该选项。
① 在MATLAB主机上用hardware emulation验证生成的代码
Real-Time Workshop Embedded Coder提供了Emulation hardware支持处理器字长不同的主机-目标机系统的代码生成。在Emulation hardware→device type中选择MATLAB
Host Computer,能生成有条件的模型代码,如数据类型的强制类型转换。
测试步骤:
把待测试的模块封装成一个子系统;
设置Emulation hardware(code generation only)面板如图5.2.13所示:
图5.2.13 Emulation hardware子面板参数
Real-Time Workshop →Interface选中Create Simulink(S-Function) block,同时不选中Enable portable word sizes选项;
在Real-Time Workshop面板,不选中“Generate code only”,则“Generate code”按钮变为“Build”按钮;
右击子系统模块,在弹出的菜单中选择Real-Time Workshop → Build Subsystem,则在弹出新的模型窗口中生成了子系统的S-function wrapper;
在主机上验证生成的代码,与原子系统的仿真结果。
②在MATLAB主机上用portable word sizes验证ERT产品级代码
Real-Time Workshop Embedded Coder软件提供了模型设置选项——Enable portable
word sizes,支持处理器字长不同的主机-目标机系统的代码生成。选择Enable portable word
sizes选项,则生成的代码中包含有条件的处理宏,使生成的源代码文件能用于SIL测试。
在图5.2.14所示的参数设置对话框的Interface面板上选择Create Simulink(S-Function)
block和Enable portable word sizes,并且Hardware Implementation面板的Emulation
hardware设置为None。
图5.2.14 Interface面板参数设置
2. 处理器在环测试
处理器在环测试(Processor-in-the-Loop,即PIL)是实现对生成代码的验证,帮助用户评价在处理器上生成的代码的运行过程,来找出由目标编译器或处理器产生的错误,验证框图如图5.2.15所示。PIL协同仿真可以帮助用户估计算法的优劣,是用于对所生成代码的处理器在环(PIL)测试新的模型仿真模式,通过PIL测试,可以在所支持的处理器上自动生成子系统代码,还可以用原始的Simulink模型自动验证生成的嵌入式代码,包括在Simulink中无法仿真的一些目标特定的代码。在利用Real-Time Workshop Embedded Coder生成代码的过程中,可以对模型或模型中的一个子系统或库中的子系统创建PIL模块。
通过链接PIL算法对象代码与wrapped代码来创建PIL应用,因为wrapped代码包含string.h头文件,所以在PIL应用中要用到memcpy函数,采用memcpy有利于Simulink
软件与协同仿真处理器间的数据交换。
在PIL协同仿真中,Real-Time Workshop为PIL算法生成可执行代码,仿真时在处理器平台上运行该代码。在每一采样间隔仿真模型,并通过CCS软件将输出信号下载到处理器平台。当处理器平台从模型中接收信号时,在每一采样步执行PIL算法,而PIL算法通过CCS界面返回Simulink软件处理的输出信号。完成仿真的一次采样循环后,在下一采样间隔再处理模型,在仿真过程中重复执行该操作。PIL测试不是实时运行的,在每一采样完成后,仿真暂停以保证Simulink测试工具与对象代码间的所有的数据都进行了交换,从而可以检查出模型和生成代码之间的不同。
Simulink测试平台测试信号算法PIL接口For Use with
TI’s Code Composer
Studio算法代码验证CCS测试平台
图5.2.15 验证PIL的框图
PIL模块
根据子系统创建的PIL模块继承了子系统的输入/输出信号名,PIL模块如图5.2.16所示。
图5.2.16 PIL模块
如果允许DSP/BIOS,则不能进行堆栈剖析,所以在对PIL模块进行堆栈剖析时,要先在模块的Target Preferences中不选中DSP/BIOS,再编译工程。
Real-Time Workshop的目标文件不支持PIL,在创建PIL模块时要选择ccslink_目标文件。
创建和使用PIL模块:
①对要进行测试的模块封装成一个模块,即选中要进行测试的模块,右击模块在弹出的菜单中选择Create Subsystem。
②打开新封装的子系统,在子系统中添加Target Preferences模块,并根据处理器型号设置Target Preferences模块的参数。
③设置模型参数使能生成PIL算法的代码和PIL模块,选择菜单Simulation->
Configuration Parameters,点击Real-Time Workshop面板,设置System target file为ccslink_。
④设置参数使模型执行PIL编译和创建PIL模块,选择Embedded IDE Link面板,在Build action列表中选择Create_processor_in_the_loop_project允许使用PIL,在PIL block
action列表中选择Create_PIL_block_build_and_download,如图5.2.17所示。
图5.2.17 Embedded IDE Link 参数设置
⑤右击模型中封装后的模块,在弹出的菜单中选择Real-Time Workshop → Build
Subsystem,如图5.2.18所示,则弹出生成的PIL模块新的模型窗口。
图5.2.18 子系统编译的菜单
5.2.4 代码的实时运行剖析
代码实时运行剖析,帮助用户了解任务在处理器硬件上的实时运行。实时剖析能够剖析同步、异步任务或单一子系统,剖析的结果输出为图形方式或HTML报告。
①任务剖析
a.打开模型的参数设置对话框,选择Embedded IDE Link面板,如图5.2.19所示。
b.选中Profile real-time execution,在Profile by列表中选择Tasks进行任务剖析。
c.选中Export IDE link handle to base workspace,并在IDE link handle name中定义一个句柄名。
图5.2.19 参数设置
查看剖析结果:在模型的工具栏点击生成代码,并编译、下载到处理器上、运行用户代码。在MATLAB命令行输入profile(handlename,‟execution‟,‟report‟)查看图形报告或HTML报告,其中handlename为用户定义的IDE链接句柄名,可在图5.2.19所示的对话框中设置,设置为CCS_Obj。
注意:在获取剖析报告时应停止程序的运行,因为从正在运行的程序中获取剖析数据会产生不正确的结果。
②子系统剖析
步骤与任务剖析一样,只是在图5.2.19所示的对话框中的Profile by列表中选择Atomic
subsystem进行子系统剖析。
5.2.5 堆栈分析
Embedded IDE Link允许用户定义处理器系统堆栈的使用,即通过profile命令可以初始化并测试堆栈的大小和利用率。堆栈剖析即在程序运行前,用profile命令写堆栈中的地址内容,运行一段时间后停止程序,用profile命令剖析地址中的内容,比较使用过的地址数和分配的总地址数即为堆栈使用率。
用户可以剖析工程中的手写代码和从模型生成的代码的堆栈,当工程中使用DSP/BIOS时,堆栈剖析报告显示堆栈利用率为100%。
当使用profile初始化并测试堆栈时,返回堆栈大小、使用率和地址等信息,通过这些
信息可以使堆栈得到充分利用。
profile(cc,‟stack‟,‟report‟)
Maximum stack usage:
System Stack:532/1024 (51.95%) MAUs used.
name: System Stack
startAddress:[512 0]
end Address:[1535 0]
stackSize:1024 MAUs
growthDirection:ascending
按下列步骤剖析系统堆栈,假设cc是已存在的ticcs对象:
①加载要剖析的程序;
②初始化堆栈状态,其中cc为对象句柄名,
profile(cc,‟stack‟,‟setup‟)
③运行程序;
④停止运行;
⑤查看堆栈剖析的结果,
profile(cc,‟stack‟,‟report‟)
5.2.6 TI C6416 DSK目标板的应用实例
通过一个非常简单的例子——LED实验来介绍嵌入式C代码的快速生成过程。其工作流程为:
设计和仿真;
软件在环测试;
快速原型建立;
代码验证;
生成和剖析代码;
堆栈使用率剖析;
生成生成代码和硬件在环测试。
1. 设计和仿真
在CCS系统配置中选择C64xx XDS510 Emulator(图5.2.20)并保存设置。
图5.2.20 处理器设置
在MATLAB命令窗口中,通过checkEnvSetup函数可以得到处理器信息,输入
checkEnvSetup('ccs', 'C6416', 'list')
得到:
图5.2.21 处理器信息
建立LED模型:
①打开一个新的Simulink模型窗口,选择View → Library Browser打开模块库,从Signal Processing Blockset库中选择Random Source模块,如图5.2.22所示,添加到新建的模型中。
图5.2.22 Signal Processing Blockset模块库
从Math Operations库中选择Gain、Rounding Function模块,如图5.2.23所示,添加到新建的模型中。
图5.2.23 Math Operations模块库
创建如图5.2.24所示的模型,指定路径和文件名,保存此模型。
图5.2.24 建立的Siumulink模型
②配置模块参数。
双击Random Source模块,打开模块参数对话框(如图5.2.25所示),设置采样时间为5s。
图5.2.25 模块参数对话框
点击按钮,开始仿真,仿真结果如图5.2.26所示。
图5.2.26 仿真结果
2. 软件在环测试
软件在环测试在于验证生成代码的有效性。即将Gain模块与Rounding Function模块封装成子系统,设置参数如下:
①在子系统的参数设置对话框的Hardware Implementation面板的Emulation
hardware子面板中如果已选择None选项则清除选择,选择Device vendor中的Generic,并在Device type中选择MATLAB Host Computer(如图5.2.27所示);
②Real-Time Workshop面板的System target file browser选择为:;
③在Interface面板中选择Create Simulink(S-Function) block,并确保Enable portable
word sizes选项未被选中;
④在Real-Time Workshop面板上,去掉“Generate code only”的默认状态,使“Generate code ”按钮变为“Build”按钮。
右击子系统模块,在弹出的菜单中选择Real-Time Workshop->Build Subsystem,则弹出新的模型窗口,生成子系统代码的S-function wrapper模块在该模型窗口中(如图5.37所示)。
图 5.2.27 S-Function wrapper模块及属性
验证模型如图5.2.28所示,仿真结果如图5.2.29所示,从仿真结果可知两者的差值Subtract恒为一条值为0的直线,说明它们实现的功能一致,即生成的代码能实现模型的功能。
图5.2.28 验证模型
图5.2.29 仿真结果
3. 快速原型建立
从Target Support Package→Supported Processors→Texas Instruments C6000→Board Support→C6416 DSK库中选择LED模块,如图5.2.30所示,添加到新建的模型中,替换Scope模块。
图5.2.30 C6416 DSK模块库
从Target Support Package → Supported Processors→Texas Instruments C6000→Target Preferences库中选择C6416DSK模块,如图5.2.31所示,添加到新建的模型中。
图5.2.31 C6000 的Target Preferences模块库
创建如图5.2.32所示的模型,指定路径和文件名C6416_,保存此模型。
图5.2.32 跑马灯模型
双击C6416DSK模块,打开模块参数对话框,如图5.2.33所示。点击Memory属性页(如图5.2.34),Sections属性页(如图5.2.35)可以看到内存分配信息,读者可根据.cmd文件修改存储空间的起始地址和存储空间的长度,以及段的内容。
图5.2.33 模块参数对话框
图5.2.34 Memory面板设置
图5.2.35 Sections面板设置
Real-Time Workshop选项的具体设置可参考前文的介绍,但特别要注意此时的Hardware Implementation面板设置:
由于Simulink模型中已包含C6000 DSK板,所以Device vendor选择Texas
Instruments;
Device type选择C6000,字节顺序为Little Endian。
Embedded IDE Link选项中的Interrupt overrun notification method选择Print_message。
4. 处理器在环测试
即进行处理器在环测试,对于led这个例子,将Gain模块与Rounding Function模块封装成子系统,生成PIL模块,如图5.2.36所示,
图5.2.36 生成的PIL模块
比较子系统与利用子系统生成的PIL模块,验证PIL模块执行的功能与原系统的一致性。模型和仿真结果分别如图5.2.37,5.2.38所示,两者的差值Subtract恒为一条值为0的直线,说明它们实现的功能一致。
图5.2.37 验证功能的模型
图5.2.38 仿真结果
5. 生成代码,剖析代码
对于LED模型,首先设置实现任务剖析的参数,然后使程序运行一段时间后停止,将得到任务剖析的结果。
在命令行中输入:
>> profile(CCS_Obj,'execution','report')
剖析结果为:
ans =
numTimerTasks: 1
wsize: 32
oRunMax: 0
tMax: 2.0560e-006
taskActivity: [16x1 char]
taskIdList: 1
taskTs: [16x1 double]
taskTicks: [16x1 double]
timePerTick: 8.0000e-009
warning: ''
taskNameList: {'Base-Rate'}
recordedTaskIdx: 1
报告如图5.2.39所示。
图5.2.39 任务剖析报告
任务剖析数据分析:
图5.2.39记录的是从t=0开始执行模型后14.000s内的数据剖析,剖析的定时器分辨率为8.000ns,具体数据如表5.2.6所示。
表5.2.6 任务剖析报告的数据分析
任务 Base-Rate
Maximum turnaround time
Average turnaround time
Maximum execution time
Average execution time
Average sample time
在t = 12.000 s时为1.984 µs
1.713 µs
在t = 12.000 s时为1.984 µs
1.713 µs
2.000 s
子系统剖析的结果为:
ans =
numTimerSubsystems: 1
wsize: 32
subsystemActivity: [28x1 char]
subsystemIdList: 1
subsysTs: [28x1 double]
subsysTicks: [28x1 double]
timePerTick: 8.0000e-009
warning: ''
subsysNameList: {'C6416_light'}
recordedSubsysIdx: 1
子系统剖析报告如图5.2.40所示。
图5.2.40 子系统的剖析报告
子系统剖析数据的分析:
图5.2.40记录的是从t=0开始执行模型后12.000s内的数据剖析,剖析的定时器分辨率为8.000ns,具体数据如表5.2.7所示。
表5.2.7 子系统剖析报告的数据分析
子系统
Maximum turnaround time
Average turnaround time
Maximum execution time
Average execution time
C6416_light
在t = 12.000 s时为1.584 µs
899.077ns
在t = 12.000 s时为1.584 µs
1.713 µs
子系统
Average sample time
C6416_light
899.077ns
6. 堆栈使用率剖析
对于led模型,在Embedded IDE Link面板设置系统堆栈大小为1024MAUs,
在命令行中输入:
>> profile(CCS_Obj,'stack','report')
得堆栈使用率报告:
Maximum stack usage:
System Stack: 0/1024 (0%) MAUs used.
name: System Stack
startAddress: [30032 0]
endAddress: [31055 0]
stackSize: 1024 MAUs
growthDirection: ascending
继续输入
run(CCS_Obj)
halt(CCS_Obj)
profile(CCS_Obj,'stack','report')
得到结果:
Maximum stack usage:
System Stack: 540/1024 (52.73%) MAUs used.
name: System Stack
startAddress: [30032 0]
endAddress: [31055 0]
stackSize: 1024 MAUs
growthDirection: ascending
7. 生成代码
通过上述的模型仿真与代码验证,点击工具栏上的按钮,RTW-EC将为LED模型自动生成嵌入式C代码。同时将生成的C代码自动加载到CCS IDE中,并编译链接成可执行文件下载到C6416 DSK板上运行。创建的工程文件如图5.2.41、代码生成报告如图5.2.42,代码跟踪报告如图5.2.43所示。
图5.2.41 生成的工程文件
在生成代码过程中,MATLAB命令行显示如下信息:
### Connecting to Code Composer Studio(tm)...
### Generating code into build directory:
…MATLABlightC6416_light_ticcs
### Invoking Target Language Compiler on C6416_
tlc
-r
……
### TLC code generation complete.
### Creating project marker file: rtw_
### Creating project:
…MATLABlightC6416_light_ccslinkC6416_
### Project creation done.
###
### Build done.
### Downloading program:
…MATLABlightC6416_light_ticcsC6416_
### Download done.
图5.2.42 生成的代码报告
图5.2.43 代码的跟踪报告
生成的工程文件中还含有地址映射文件(MAP文件),通过查阅该文件可以了解程序、数据及IO空间的占用信息。如图5.2.44所示:
图5.2.44 MAP文件
8. 硬件在环测试
①需求:C6416 DSK板上的四个LED指示灯随机点亮。
当输入值为0时,灯灭;当输入非零值时,灯亮,输入值范围在0——15之间。
例如,输入值为6,即0110时,中间两个灯亮,两边的灯灭;若输入值为13,即1101时,则第0、1、3号灯亮,第2号灯灭。
②测试实验:当输入为13时,验证C6416 DSK板上的第0、1、3号灯是否点亮。
硬件在环测试模型如图5.2.45所示,按前面介绍的方法为测试LED模型生成嵌入式C代码,并下载到C6416 DSK板上运行,硬件在环测试结果如图5.2.46所示。从实验结果来看,0、1、3号LED点亮,证明自动生成的嵌入式C代码运行正确,设计满足需求分析的要求。
图5.2.45 硬件在环测试LED模型
图5.2.46 硬件在环测试结果
5.2.7 用户自定义目标板的应用
1.驱动程序开发
当用户使用自定义的硬件模块时,需编写设备驱动程序,设备驱动程序为用户手写代码的S-function、Embedded MATLAB等自定义模块。为生成设备驱动代码模块,需添加硬件特有的设备驱动代码和S-function代码,其中硬件特有设备驱动代码用于处理实时程序与I/O设备之间的联系,S-function代码用于实现应用程序界面所需的模型初始化、输出和其他函数,然后通过RTW-EC自动生成代码。详细内容请读者查阅参考文献[14]、[21]。
2.用户自定义目标板的代码生成
步骤:
①创建应用模型;
②从Target Preferences 模块库中选择Custom Board添加至模型中,根据硬件设置模块参数;
③设置模型的配置参数,包括Solver参数和Real-Time Workshop选项;
④生成工程文件;
⑤在CCS中查看生成的工程文件。
3.实例
下面通过一个软仿真的例子来介绍如何为用户自定义的目标板生成实时代码。
①为CCS系统配置相应的配置文件,在Setup CCStudio v3.3中选择F2812软仿真,如图5.2.47所示。
图5.2.47 CCStudio设置
②创建模型,并添加Custom Board模块(图5.2.48),双击Custom Board模块打开模块对话框,在对话框中的处理器列表中选择用户的处理器型号,根据处理器型号系统会自动修改CPU clock频率,如图5.2.49所示。并验证Memory和Sections的设置,确保是正确的。
图5.2.48 硬件模型
图5.2.49 模块属性
③按照5.2.1节的介绍设置模型的仿真参数与Real-Time Workshop选项。
④点击工具栏按钮将自动生成包含代码的工程文件。如图5.2.50所示:。
在生成代码过程中,MATLAB命令行显示如下信息:
### Connecting to Code Composer Studio(tm) ...
### Generating code into build directory: …MATLABexaas_ticcs
### Invoking Target Language Compiler on
tlc
-r
……
### Loading TLC function libraries
......
### TLC code generation complete.
### Creating project marker file: rtw_
### Creating project: …MATLABexaas_
### Project creation done.
### Project creation done.
###
### Build done.
### Downloading program: …MATLABexaas_
### Download done.
⑤在CCS中查看生成的工程文件,并编译、链接该工程文件。
图5.2.50 CCS 中的工程文件
5.2.8 其他目标板的应用
MATLAB还支持其他厂商的芯片,只需在参数设置的Hardware Implementation面板选择相应的设备类型即可。下面以MSP430和ARM7为例介绍代码的生成过程:
1. 设备为MSP 430
图5.34所示的模型,在Hardware Implementation→Device vendor中,选择Texas
Instruments;Device type选中MSP430。如图5.2.51所示:
图5.2.51 Hardware Implementation面板设置
参考5.2.1节的介绍,在Optimization面板上,设置代码的优化参数;
在Real-Time Workshop面板中,设置System target file browser为,Compiler
optimization level选择为Custom,将Custom compiler optimization flags指定为o2,如图5.2.52所示:
图5.2.52 Real-Time Workshop面板设置
在Report面板上选中Create code generation report,则会给出生成代码的报告。如图5.2.53所示:
图5.2.53 Report面板设置
点击按钮将自动为模型生成代码,打开代码报告,如图5.2.54所示。
图5.2.54 代码报告
2. 设备为ARM 7
对图5.34所示的模型,在Hardware Implementation→Device vendor中,选择Texas
Instruments;Device type选择ARM 7,其他设置和图5.62、5.63中的相同。如图5.2.55所示:
图5.2.55 Hardware Implementation面板设置
点击按钮将自动为模型生成代码,打开代码报告,如图5.2.56所示。
图5.2.56 代码报告
5.3 MATLAB与CCS的交互式开发
Embedded IDE Link工具,使MATLAB、CCS软件和DSP硬件有机结合起来,对DSP程序进行实时分析,测试和验证。即通过在MATLAB中创建对象,来操作DSP中的register或memory。实现在MATLAB环境下完成对CCS的操作,从而方便了DSP开发的调试工作。
RTDX(Real-Time Data Exchange)在MATLAB和DSP器件之间搭起一座数据交换的桥梁,而无须停止目标DSP的运行,从而能实时的、连续的观察目标DSP的运行状况。
RTDX利用JTAG仿真器实现了MATLAB与DSP之间的无缝连接,它几乎不占用DSP的资源,让数据交换在应用程序的后台执行。这使得程序调试变得异常容易。对于R2009b版,MATLAB不再支持C6000 DSP与之进行实时数据交换,只保留了对C5000、C2000 DSP
的RTDX支持。
Embedded IDE Link中提供了多种函数对CCS IDE连接对象和RTDX连接对象进行操作,如配置处理器、打开和使能通道、向处理器发送数据等。操作函数如表5.3.1和5.3.2所示:
表5.3.1 CCS IDE连接对象的操作函数
函数名
ticcs
cd
open
run
描述
创建连接对象
改变CCS IDE的工作路径
在CCS IDE中加载文件
运行目标程序
函数名
close
configure
disable
display
enable
isenabled
isreadable
iswritable
msgcount
open
readmat
readmsg
writemsg
表5.3.2 RTDX连接对象的操作函数
描述
关闭MATLAB软件与用户处理器之间的RTDX连接
配置RTDX通道缓冲器
在关闭RTDX连接前禁用连接
返回RTDX连接对象的属性
使能打开RTDX通道
确定是否使能RTDX通道
确定是否能读指定的RTDX通道
确定是否能写指定的RTDX通道
确定在通道队列里等待的信息数目
打开一个RTDX通道
从指定的RTDX通道中将数据读入矩阵中
从指定的RTDX通道中读信息
向指定的RTDX通道中写信息
在MATLAB命令窗口输入rtdxtutorial并运行,可查看一个简单的目标DSP应用的例子。
使用连接对象操作函数的步骤如下:
①选定目标板;
②创建目标处理器的RTDX连接对象;
③将程序加载到处理器中;
④配置与处理器连接的通道;
⑤在MATLAB环境下对RTDX连接对象进行操作;
⑥关闭与处理器的连接,并清除RTDX连接对象。
在利用RTDX通道进行数据传递之前,必须打开并使能这些RTDX通道,打开的通道名必须在目标处理器加载的应用程序中已经定义和声明。可在源代码文件中添加如下语句来创建RTDX通道:
rtdx_CreateInputChannel(ichan);
%创建一个通道名为ichannel的RTDX输入通道
rtdx_CreateOutputChannel(ochan);
%创建一个通道名为ochannel的RTDX输出通道
5.3.1 选定目标板
用户根据所采用的DSP目标板,在CCS开发环境中配置系统,本例中是设置了两片DSP,一个是采用F28xx芯片的软仿真设置,另一个是采用F2812芯片并通过XD560的硬仿真设置。设置完处理器后就可以通过MATLAB来实现DSP的系统开发和调试等。
版权声明:本文标题:5-嵌入式代码的快速生成0222 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1706073429h500750.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论