主要内容

生成C代码MATLAB代码

MATLAB®编码器™从函数和System对象生成高度优化的ANSI C和c++代码DSP系统工具箱.您可以在各种各样的应用程序中部署此代码。

类生成C代码利用高能FFT系数构造正弦信号示例并从生成的代码构建可执行文件。

下面是这个例子的MATLAB代码:

L = 1020;Sineobject = dsp。SineWave (“SamplesPerFrame”L,...“PhaseOffset”10“SampleRate”, 44100,“频率”, 1000);Ft = dsp。FFT (“FFTImplementation”“FFTW”);Ift = dsp。传输线(“FFTImplementation”“FFTW”“ConjugateSymmetricInput”,真正的);rng (1);numIter = 1000;Iter = 1:numIter Sinewave1 = Sineobject();Input = Sinewave1 + 0.01*randn(size(Sinewave1));FFTCoeff = ft(输入);FFTCoeffMagSq = abs(FFTCoeff).^2;能量freqdomain = (1/L)*sum(FFTCoeffMagSq);[FFTCoeffSorted, ind] = sort(((1/L)*FFTCoeffMagSq),1,“下”);CumFFTCoeffs = cumsum(FFTCoeffSorted);EnergyPercent = (CumFFTCoeffs/EnergyFreqDomain)*100;Vec = find(EnergyPercent > 99.99);FFTCoeffsModified = 0 (L,1);FFTCoeffsModified(ind(1:Vec(1))) = FFTCoeff(ind(1:Vec(1)));ReconstrSignal = ift(FFTCoeffsModified);结束马克斯(abs (Input-ReconstrSignal))情节(输入,‘*’);持有;情节(ReconstrSignal“o”);持有

您可以在MATLAB环境中运行生成的可执行文件。此外,您可以将代码打包并重新定位到另一个没有安装MATLAB的开发环境中。方法生成代码MATLAB编码器App或codegen(MATLAB编码器)函数。方法的工作流codegen函数。有关应用程序工作流的更多信息,请参见使用MATLAB Coder App生成C代码(MATLAB编码器)

设置编译器

第一步是设置一个受支持的C编译器。金宝appMATLAB编码器自动定位并使用支持的已安装编译器。金宝app可以使用更改默认编译器墨西哥人设置.详情请参见更改默认编译器.有关受支持的编译器的当前列表,请参见金宝app金宝app支持和兼容的编译器

将算法的计算部分分解为一个MATLAB函数

要生成C代码,入口点必须是一个函数。您不必为整个MATLAB应用程序生成代码。如果你有特定的部分是计算密集型的,从这些部分生成代码,以加快你的算法。调用此MATLAB函数的线束或驱动器不需要生成代码。该套具在MATLAB中运行,可以包含可视化和其他验证工具,这些工具实际上不是被测系统的一部分。例如,在利用高能FFT系数构造正弦信号的例子中,情节函数绘制输入信号和重建信号。情节不支持代码生成金宝app,必须保持使用。要从包含可视化工具的工具中生成代码,请将工具重写为函数,并将可视化函数声明为使用的外部函数coder.extrinsic(MATLAB编码器).要运行生成的包含外部函数的代码,必须在计算机上安装MATLAB。

的MATLAB代码使用高能FFT系数重建原始信号的环路是该算法的计算密集型部分。加快通过将这个计算部分移动到它自己的函数中,GenerateSignalWithHighEnergyFFTCoeffs.m

L = 1020;Sineobject = dsp。SineWave (“SamplesPerFrame”L,...“SampleRate”, 44100,“频率”, 1000);rng (1);numIter = 1000;Iter = 1:numIter Sinewave1 = Sineobject();Input = Sinewave1 + 0.01*randn(size(Sinewave1));[ReconstrSignal,numCoeff] = GenerateSignalWithHighEnergyFFTCoeffs(Input);结束马克斯(abs (Input-ReconstrSignal))图(1);情节(输入);情节(ReconstrSignal‘*’)举行
函数[ReconstrSignal,numCoeff] = GenerateSignalWithHighEnergyFFTCoeffs(Input) ft = dsp。FFT (“FFTImplementation”“FFTW”);Ift = dsp。传输线(“FFTImplementation”“FFTW”“ConjugateSymmetricInput”,真正的);FFTCoeff = ft(输入);FFTCoeffMagSq = abs(FFTCoeff).^2;L = size(输入,1);EnergyF = (1/L)*sum(FFTCoeffMagSq);[FFTCoeffSorted, ind] = sort(((1/L)*FFTCoeffMagSq),1,“下”);CumFFTCoeffs = cumsum(FFTCoeffSorted);EnergyPercent = (CumFFTCoeffs/EnergyF)*100;Vec = find(EnergyPercent > 99.99);FFTCoeffsModified = 0 (L,1);FFTCoeffsModified(ind(1:Vec(1))) = FFTCoeff(ind(1:Vec(1)));numCoeff = Vec(1);ReconstrSignal = ift(FFTCoeffsModified);结束

使代码适合代码生成

在生成代码之前,必须为代码生成准备MATLAB代码。

在设计时检查问题

第一步是消除不受支持的构造,并检查任何代码生成问题。金宝app所支持的DSP系统工具箱功能的列表金宝appMATLAB编码器,请参阅C代码生成支持的函数和系统对象金宝app有关受支持的语言构造的列表,金宝app请参见支持C/ c++代码生成的MATLAB语言特性金宝app(MATLAB编码器)

代码分析器在您在设计时输入代码时检测编码问题。要启用代码分析程序,必须添加% # codegenpragma到你的MATLAB文件。

代码生成准备工具筛选MATLAB代码中不支持代码生成的特性。金宝app访问该工具的方法之一是右键单击当前文件夹中的MATLAB文件。运行代码生成工具GenerateSignalWithHighEnergyFFTCoeffs.m没有发现问题。

在代码生成时检查问题

在生成C代码之前,请确保MATLAB代码成功生成了MEX函数。的codegen(MATLAB编码器)用于生成MEX函数的命令用于检测阻止代码生成的任何错误。

运行codegenGenerateSignalWithHighEnergyFFTCoeffs.m函数。

codegenarg游戏{输入}GenerateSignalWithHighEnergyFFTCoeffs

MATLAB命令提示符中出现如下信息:

???左边被限制为非复数,但右边是复数。要纠正这个问题,可以使用函数real将右边的变量变为实数,或者使用complex函数将左边变量的初始赋值改为复数值。Error in ==> GenerateSignalWithHighEnergy Line: 24 Column: 1 Code generation failed: View Error Report Error using codegen

这条消息引用了变量FFTCoeffsModified.编码器希望将该变量初始化为复杂变量。要解决此问题,请初始化FFTCoeffsModified变量是复数。

FFTCoeffsModified = 0 (L,1)+0i;

重新运行codegen函数,可以看到在当前文件夹中成功生成了一个MEX文件.mex扩展。

codegenarg游戏{输入}GenerateSignalWithHighEnergyFFTCoeffs

在运行时检查问题

运行生成的MEX函数,查看是否报告了任何运行时问题。要做到这一点,请替换

[ReconstrSignal,numCoeff] = GenerateSignalWithHighEnergyFFTCoeffs(Input);
[ReconstrSignalMex,numCoeffMex] = GenerateSignalWithHighEnergyFFTCoeffs_mex(Input);
在背带里面。

挽具现在看起来像:

L = 1020;Sineobject = dsp。SineWave (“SamplesPerFrame”L,...“SampleRate”, 44100,“频率”, 1000);rng (1);numIter = 1000;Iter = 1:numIter Sinewave1 = Sineobject();Input = Sinewave1 + 0.01*randn(size(Sinewave1));[ReconstrSignalMex,numCoeffMex] = GenerateSignalWithHighEnergyFFTCoeffs_mex(Input,L);结束马克斯(abs (Input-ReconstrSignalMex))图(1);情节(输入);情节(ReconstrSignalMex‘*’)举行

代码成功运行,表明没有运行时错误。

将MEX功能与仿真进行比较

注意,与常规函数相比,使用MEX函数时,线束运行得更快。生成MEX函数的原因不仅是为了检测代码生成和运行时问题,而且还为了加快算法的特定部分。有关示例,请参见信号处理算法的MATLAB加速

您还必须检查来自MEX的数字输出结果与常规函数是否匹配。比较两种方法所产生的重构信号GenerateSignalWithHighEnergyFFTCoeffs.m函数及其对应的MEX函数GenerateSignalWithHighEnergyFFTCoeffs_mex

max(abs(ReconstrSignal-ReconstrSignalMex)) ans = 2.2204e-16

结果非常匹配,证实代码生成是成功的。

生成一个独立的可执行文件

如果您的目标是在MATLAB环境中运行生成的代码,那么您的构建目标可以是一个MEX函数。如果目标是将代码部署到另一个应用程序,那么从整个应用程序生成一个独立的可执行文件。为此,驾驭必须是调用子函数的函数GenerateSignalWithHighEnergyFFTCoeffs.将挽具重写为函数。

函数reconstructSignalTestbench() L = 1020;Sineobject = dsp。SineWave (“SamplesPerFrame”L,...“SampleRate”, 44100,“频率”, 1000);rng (1);numIter = 1000;Iter = 1:numIter Sinewave1 = Sineobject();Input = Sinewave1 + 0.01*randn(size(Sinewave1));[ReconstrSignal,numCoeff] = GenerateSignalWithHighEnergyFFTCoeffs(Input,L);结束

记录输入和重建信号的所有1000帧以及用于重建信号的每一帧的FFT系数的数量。将所有这些数据写入一个名为data.bin使用dsp。BinaryFileWriter系统对象™。这个例子记录了系数的数量,这些系数是标量值,作为输入信号和重建信号的每一帧的第一个元素。要写入的数据的帧大小为l+ 1,格式如下图所示。

N为表示当前输入帧信号能量99.99%的FFT系数数。二进制文件的元数据指定了这一信息。释放二进制文件写入器并在最后关闭二进制文件。

更新的挽具功能,reconstructSignalTestbench,如图所示:

函数reconstructSignalTestbench() L = 1020;Sineobject = dsp。SineWave (“SamplesPerFrame”L,...“SampleRate”, 44100,“频率”, 1000);头= struct(“FirstElemInBothCols”“系数数”...“FirstColumn”“输入”“SecondColumn”“ReconstructedSignal”);BFW = dsp。BinaryFileWriter (“data.bin”“HeaderStructure”,头);numIter = 1000;M = l +1;ReSignalAll = 0 (M*numIter,1);InputAll = 0 (M*numIter,1);rng (1);Iter = 1: numIter Sinewave1 = Sineobject();Input = Sinewave1 + 0.01*randn(size(Sinewave1));[ReconstrSignal,numCoeffs] = GenerateSignalWithHighEnergyFFTCoeffs(Input);InputAll (((Iter-1) *米)+ 1:Iter *米)= (numCoeffs;输入);ReSignalAll((Iter-1)*M)+1:Iter*M) = [numCoeffs;ReconstrSignal];结束"自行车造福世界"组织([InputAll ReSignalAll]);释放(");

生成C可执行文件的下一步是创建一个coder.config对象作为可执行文件,并提供c函数赋给该对象。

CFG = code .config(exe”);cfg。CustomSource =“reconstructSignalTestbench_Main.c”

以下是如何reconstructSignalTestbench_Main.c函数查找这个示例。

版权所有2017 The MathWorks, Inc. */ #include  #include  #include " reconstructsignaltestbench_initial .h" #include "reconstructSignalTestbench_terminate.h" int main() {reconstructSignalTestbench_initialize();reconstructSignalTestbench ();reconstructSignalTestbench_terminate ();返回0;}

有关创建主函数的其他详细信息,请参见从MATLAB代码生成独立的C/ c++可执行文件(MATLAB编码器)

设置CustomInclude属性指定主文件的位置。在本例中,位置为当前文件夹。

cfg。CustomInclude = [“””pwd,“””];

在MATLAB命令提示符中运行以下命令生成C可执行文件:

codegen配置cfg报告reconstructSignalTestbench

MATLAB编码器类生成的C代码编译并链接主函数reconstructSignalTestbench.m

如果你使用的是Windows,你可以看到reconstructSignalTestbench.exe在当前文件夹中生成。如果您使用的是Linux,则生成的可执行文件没有. exe扩展。

读取和验证二进制文件数据

运行可执行文件创建一个二进制文件,data.bin,并写入输入,重构信号,以及用于重构信号的FFT系数的数量。

reconstructSignalTestbench !

方法从二进制文件中读取此数据dsp。BinaryFileReader对象。为了验证数据是否正确写入,请在MATLAB中从二进制文件中读取数据,并将输出与变量进行比较InputAll而且ReSignalAll

头文件原型必须具有与写入文件的头文件结构相似的结构。将数据读取为两个通道。

M = 1021;numIter = 1000;headerPro = struct(“FirstElemInBothCols”“系数数”...“FirstColumn”“输入”“SecondColumn”“ReconstructedSignal”);BFR = dsp。BinaryFileReader (“data.bin”“HeaderStructure”...headerPro,“SamplesPerFrame”, M * numIter,“NumChannels”2);数据= bfr();

比较第一个频道与InputAll第二个频道ReSignalAll

isequal (InputAll、数据(:1))
Ans =逻辑1
isequal (ReSignalAll、数据(2):,)
Ans =逻辑1

结果完全匹配,说明写操作成功。

将代码重新定位到另一个开发环境

一旦从MATLAB算法生成代码,就可以将代码重新定位到另一个开发环境,例如不包括MATLAB的系统或集成开发环境(IDE)。方法将文件打包到压缩文件中packNGo函数在命令行或选项中的MATLAB编码器有关说明这两个工作流的示例,请参见用于其他开发环境的包代码(MATLAB编码器).有关的更多信息packNGo选项,看到packNGo环球套票。BuildInfo方法(MATLAB编码器).您可以使用标准的zip实用程序重新定位和解压缩zip文件。有关如何打包本例中生成的可执行文件的示例,请参见将MATLAB代码生成的代码迁移到另一个开发环境

另请参阅

功能

相关的话题

外部网站