您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > 从MATLAB到嵌入式C代码的实现
从MATLAB到嵌入式C代码的实现从设想到硬件实现的鸿沟是许多从事嵌入式开发的工程师们都熟悉的问题。鉴于MATLAB本身的语言特点、强大的函数库和灵活性,算法开发人员经常在算法的概念设计阶段使用它。随着设计发展到嵌入式应用阶段,真实环境下的实际限制就需要考虑。这往往需要手工地把MATLAB指令翻译成c代码。手工翻译就涉及将MATLAB中方便易行的矩阵计算用c重新实现,这最终导致了同样算法的不同语言版本。在这一阶段,用户需要在多次循环设计时面临验证不同版本的等效性这一额外负担。验证所花费的精力很快就超出开发人员的承受范围,导致设计不是过快固化就是偏离了最初的定义。最近TheMathWorks公司提供了解决该问题的工具。这个工具能够把一种已明确定义的MATLAB语言子集自动转化为嵌入式c代码,有效减少了MATLAB语言向c代码进行手工翻译的开发和验证成本。在本篇文章中,我们首先回顾MATLAB在早期设计过程中一些有用的特点。接下来我们要检验从MATLAB“概念”代码人工编译到C代码的低效性,之后会介绍一种不同的工作流程,即直接在MATLAB而不是使用c语言对嵌入式系统进行确切描述。MATLAB和C代码特点比较表1比较了MATLAB和c代码在前期开发中的特点。把一段典型的MATLAB算法转化成嵌入式c代码,要涉及几个相关实现的要求:?数据类型管理一在执行前必须定义数据类型。例如在图像处理中,一般用8位无符号整数表示像素值,在音频处理时,一般用16位符号整数表示采样值。而MATLAB中默认使用的64位双精度变量显然没有有效地利用内存。?内存静态分配-MATLAB在运行时无缝处理变量大小的动态变化。然而在嵌入式系统实际应用中,我们尽量避免动态内存分配,而是在使用之前给内存分配固定的大小和数据类型。?降低计算复杂性和内存占用空间,在把高层算法映射到有限内存和计算资源的硬件上,嵌入式软件设计者会耗费大量精力,同时要保证程序的有效运行。这是一个把设计算法转化成目标处理器中的指令集合和数据定义的过程。?支持定点在嵌入式软件或硬件上运行程序,需要整个算法全部严格定义成定点数据类型。工程师们一般会在把MATLAB算法改写成c代码的时候做这些调整,从而产生了我们前面所说的设计鸿沟。软件工程师在两者间进行翻译的时候,有可能会人工引入一些错误和数值上的改变。如果这些变动目的在于优化程序,算法的设计者就需要更改MATLAB程序从而使两者保持一致。但这个过程引入了不必要的工作量和产生错误的可能性。一种为嵌入式系统设计的基于嵌入式MATLAB的工作流程解决了这个问题。由MATLAB程序生成嵌入式C代码不同于其他MATLAB程序,嵌入式MATLAB语言不是对设计的抽象数学表述,它包含了高效嵌入式c指令所需要的所有细节。任何按照嵌入式MATLAB子集要求编写的MATLAB程序都能生成嵌入式c代码。为确保MATLAB算法与嵌入式MATLAB子集的一致性,需要用户遵守MATLAB子集规定的过程:?设置变量的数据类型一可以在MATLAB主程序或编译过程中设定数据类型。因为它允许一个单独的MATLAB函数产生多个使用不同的数据类型、维度和复杂度的c函数变量,因此在编译过程中设置数据类型更为方便。由于用户在函数接口已定义了数据类型和大小,在函数主体中数据类型和大小的变化就可以被自动推断了。?设置数列大小变化避免动态数据分配一在MATLAB中,在循环迭代中变量的大小也是可以改变的。用户可以通过使用固定最大值的缓存并对分部寻址的方法来解决嵌入式系统数列大小变化的问题。?编写适应于嵌入式MATLAB的函数一不是所有的MATLAB工具箱函数都适用于嵌入式MATLAB子集。这些工具箱函数可以作为模板或者参考,为用户使用嵌入式MATLAB子集在有限计算和存储资源的情况下实现类似功能的高效嵌入式c语言提供帮助。之后我们想要的c代码就可以从嵌入式MATLAB代码中自动生成了。?把浮点计算转化为定点计算一用户可以使用FixedPointToolbox中的datalogging和data-typeoverride工具来观察MATLAB算法中变量动态变化范围。这些工具箱帮助用户在MATLAB中把算法转化成优化的定点计算形式。由于这个算法是在MATLAB中编写的,用户可以直接对比定点计算和浮点计算的结果,以保证两者之间的差距在一个可接受的范围内。嵌入式MATLAB例子下面我们来举例说明在嵌入式MATLAB中进行算法的语言转换的过程。首先编写算法的概念程序并加入嵌入式系统的限制,保证程序服从于嵌入式MATALB的要求并在功能上与原程序保持一致。然后从MATLAB桌面自动生成c代码。我们选择一个图像处理中自适应中值滤波算法的例子进行具体说明。这个例子涉及了MATLAB中典型的改变变量大小的问题。MATLAB程序如图1所示,adapive_stats.m选取围绕给定元素数的矩阵的较大区域来计算该区域的统计特性(最小值,最大值,中值)。这个函数在这些统计数据的基础上给出滤波后矩阵中心元素的结果,包括两个步骤。步骤1:验证与嵌入式MATLAB子集的适用性要验证该函数是否适用于嵌入式MATLAB子集,这里推荐使用EMLMEX指令。EMLMEX在对嵌入式MATLAB程序进行编译时检测其中所有可能的语法错误,并自动生成编译报告,对问题进行描述并提供出现错误的语句在程序中的链接。编译报告显示原始函数的不适应,原因是五个变量(windowjnd,region,rmin,rmax,rmed)随着变量s在循环中采用不同数值改变了大小。不符合嵌入式MATLAB要求的函数部分在图1中被高亮显示。这个结果违反了前面提到的第二条适应性原则:设置数列大小变化避免动态数据分配。如果我们手工把这个函数改写成c代码,这五个变量将会被分配到动态存储器,这是我们所不希望看到的。解决办法是提出一个新的函数,在恒定最大值矩阵的研究区域上运行。修改后的程序如图2所示。这个程序除了不违反数值大小变化规定和调用新函数mi_stats.m之外,和原来的函数是一样的。这个新函数在图2中被高亮标示出来。可以看到在新函数roi_stats.m中,MATLAB被进行了一些面向应用的优化,比如去除了多重调用函数的开销,降低了计算的复杂程度,通过给同一分类数列标序得到3个统计表。嵌入式MATLAB子集支持很多MATLAB的结构、算子和功能。在图3中可以看到mysoft是一个用来给数列的子部分分类的MATLAB函数。运行EMLMEX命令后可以看到没有报错信息,我们可以确定改动后的adaptive_stats_roi.m现在适用于嵌入式MATLAB,并准备好自动生成C代码了。另外也可以使用MATLABM-lint检验工具来鉴别程序中适用性的问题。步骤2:适应程序的自动c代码生成EMLC是一个自动把MATLAB适应程序翻译成c源代码的命令行工具。用户可以使用下面的命令把适用程序adaptive_stats_roi.m生成C代码。emlcadaptive_stats_roi.meg(In)-c-report这里,-report选项允许用户生成一个带有C源文件超链接的HTML报告,和一个从MATLAB函数自动生成的头文件。用户可以方便地把已有的C代码整合到嵌入式MALTAB流程中。如果用户已经开发了一个C函数库,也许会希望在程序中重复利用他们。嵌入式MATLAB提供了c程序接口程序eml.ceval,允许用户在嵌入式MATLAB中调用外部C函数。例如在roi_stats.m;程序中,可以把调用MATLAB函数mysort替换成已有的c函数ic_sort:Boolc_sort(float*U,flat*Y,intn,intm);这个替换就涉及了eml.ceval函数的使用,它把输入输出参数数值或参量传递给c函数。结语使用嵌入式MATLAB子集进行代码生成的主要目的在于消除从设想到硬件实现之间的鸿沟。它引入了在同一语言环境下进行算法设计和详细描述的全新流程。通过使用MATLAB自动生成c代码,用户得以保持其设计的唯一性,迭代跟踪也变得更加简单,算法设计人员和软件工程师得以更紧密地合作,以快速生产出更完美的产品。
本文标题:从MATLAB到嵌入式C代码的实现
链接地址:https://www.777doc.com/doc-5868647 .html