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支持和兼容的编译器.
要生成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编码器).
代码分析器在您在设计时输入代码时检测编码问题。要启用代码分析程序,必须添加% # codegen
pragma到你的MATLAB文件。
代码生成准备工具筛选MATLAB代码中不支持代码生成的特性。金宝app访问该工具的方法之一是右键单击当前文件夹中的MATLAB文件。运行代码生成工具GenerateSignalWithHighEnergyFFTCoeffs.m
没有发现问题。
在生成C代码之前,请确保MATLAB代码成功生成了MEX函数。的codegen
(MATLAB编码器)用于生成MEX函数的命令用于检测阻止代码生成的任何错误。
运行codegen
在GenerateSignalWithHighEnergyFFTCoeffs.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函数的原因不仅是为了检测代码生成和运行时问题,而且还为了加快算法的特定部分。有关示例,请参见信号处理算法的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代码生成的代码迁移到另一个开发环境.
codegen
(MATLAB编码器)