主要内容

生成从文件中读取数据的代码

此示例说明如何从读取文件数据的 MATLAB® 函数生成 C 代码。

检查数据文件

在此示例中,您生成代码以读取 mydata.csv,这是逗号分隔值 (CSV) 格式的文件。此文件包含几天内不同时间的炉温(以摄氏度为单位)的测量值。该文件包含几行描述,后跟 CSV 格式的数据。

type mydata.csv
Temperature of a furnace in degrees Celsius
measured at various times over a course of 
one week
time, temp
19-Aug-2021 10:32:35, 81
20-Aug-2021 10:40:28, 72
22-Aug-2021 10:19:36, 98
23-Aug-2021 11:00:02, 70
24-Aug-2021 10:54:27, 90
25-Aug-2021 11:03:00, 87

创建并测试入口函数

创建一个 MATLAB 函数 my_readtable 以读取数据文件 mydata.csv。该函数忽略初始描述行,并创建一个包含 datetime 和数值的 MATLAB table。由于代码生成不支持 MATLAB 函数 readtablemy_readtable 函数使用低级文件 I/O 函数(如 fopenfgetlfscanffeoffclose)打开、读取和关闭文件。

type my_readtable.m
function T = my_readtable(filename,numRecords) %#codegen

f = fopen(filename,"r");

% Scan and ignore a variable number of description lines at the beginning
% of the CSV file.
line = fgetl(f);
coder.varsize("line");
while(~ismember(',',line))
    line = fgetl(f);
end

% Table variable names.
names = {'time' 'temp'};

% Initialize variables. Define 'months' cell array that is used to convert
% name of month to serial number of month in the next code block.
i = 1;
months = {'Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec'};

dateAndTime = repmat(datetime,1,numRecords);
temperature = zeros(1,numRecords);

% Read each line in the CSV file till you reach EOF. Construct an array of
% datetime and double values (for time and temp columns).
while(~feof(f))
    day = fscanf(f,'%u-');
    month_name = string(fscanf(f,'%3c',1));
    month_number = find(month_name == months);
    [result,count] = fscanf(f,'-%u %u:%u:%u, %u');

    % Check that the last fscanf call read all remaining data in the line
    assert(count == 5) 

    year = result(1);
    hour = result(2);
    minute = result(3);
    second = result(4);
    dateAndTime(i) = datetime(year,month_number,day,hour,minute,second);
    temperature(i) = result(5);
    i = i + 1;
end

% Construct the table from the values read in the previous code block.
T = table(dateAndTime',temperature','VariableNames',names);
fclose(f);

end

此入口函数(您为其生成代码的顶层 MATLAB 函数)使用这些编码模式,使其适合代码生成:

  • 字符向量 line 的大小随着函数读取初始描述的每行而变化。coder.varsize 指令指示代码生成器生成为变量 line 动态分配内存的代码。

  • 该函数对列标题名称 'time''temp' 进行硬编码,而不是在运行时从 CSV 文件中读取它们。这是因为代码生成要求表变量名称是编译时常量。

  • 变量 months 定义为字符数组而不是字符串数组,因为代码生成不支持字符串数组。

  • 该函数在 while 循环中对数组 dateAndTimetemperature 填充实际数据之前对其预初始化。

运行 MATLAB 入口函数。

T_matlab = my_readtable("mydata.csv",6)
T_matlab=6×2 table
            time            temp
    ____________________    ____

    19-Aug-2021 10:32:35     81 
    20-Aug-2021 10:40:28     72 
    22-Aug-2021 10:19:36     98 
    23-Aug-2021 11:00:02     70 
    24-Aug-2021 10:54:27     90 
    25-Aug-2021 11:03:00     87 

使用 MEX 函数测试生成的代码

要在 MATLAB 环境中测试代码生成的输出,请生成并运行 MEX(MATLAB 可执行文件)函数。MEX 函数是在 MATLAB 环境中运行的已编译 C/C++ 函数。在命令行中使用 codegen 命令生成一个 MEX 函数。

codegen 命令中,为函数 my_readtable 的输入参量指定以下数据类型:

  • filename 是无界可变长度字符串

  • numRecords 是双精度标量

s = "mystring";
t = coder.typeof(s);
t.Properties.Value = coder.typeof('a',[1 inf]);

codegen my_readtable -args {t,0} -report
Code generation successful: View report

代码生成器生成 MEX 函数 my_readtable_mex。使用用于测试 MATLAB 函数的相同值来运行生成的 MEX 函数。

T_mex = my_readtable_mex("mydata.csv",6)
T_mex=6×2 table
            time            temp
    ____________________    ____

    19-Aug-2021 10:32:35     81 
    20-Aug-2021 10:40:28     72 
    22-Aug-2021 10:19:36     98 
    23-Aug-2021 11:00:02     70 
    24-Aug-2021 10:54:27     90 
    25-Aug-2021 11:03:00     87 

生成独立 C 代码。

使用 codegen 命令为 my_readtable 生成静态 C 库。生成的库可以部署在目标硬件上。

codegen -config:lib my_readtable -args {t,0} -report
Code generation successful: View report

文件 I/O 函数在 MEX 函数和独立代码中的实现方式不同。例如,在 MEX 代码生成期间,代码生成器自动将 fscanf 视为外部函数。这意味着生成的 MEX 函数将 fscanf 调用调度给 MATLAB 引擎来执行。相反,当您生成独立代码时,代码生成器为 fscanf 函数的主体生成 C/C++ 代码。

如果您生成 MEX 函数,但希望为外部函数生成 C/C++ 代码,请通过将 coder.MexCodeConfig 对象的 ExtrinsicCalls 属性设置为 false 来禁用外部函数调用。或者,在“代码生成设置”对话框中,清除Keep extrinsic calls参数。

如果您有 Embedded Coder®,可以在部署前使用软件在环 (SIL) 或处理器在环 (PIL) 执行来验证生成的独立代码。请参阅SIL and PIL Verification for Deployment on Raspberry Pi (Embedded Coder)

另请参阅

| | | |

主题