上一篇文章中,介绍了DBC中SignalGroup的提取,对于已经提取好的Group信息,就可以批量操作生成Simulink BUS及Simulink接口模型了。本文介绍这部分的脚本实现。
通过对前面导出的m文件分析,在第一个数据需要特殊处理,其他的正常按字符串写入就好了。参考代码如下:
for i = 1:length(can_signal_group_Struct)
GroupName = can_signal_group_Struct(i).GroupName;
outputParameter_str = strcat(GroupName,' = ',' Simulink.Bus;\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat(GroupName,'.Description',' = '''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat(GroupName,'.DataScope',' = ''Auto'';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat(GroupName,'.HeaderFile',' = ''Rte_Type.h'';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat(GroupName,'.Alignment',' = -1;\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat(GroupName,'.PreserveElementDimensions',' = false;\n');
fprintf(fid,outputParameter_str);
for j = 1 : length(can_signal_group_Struct(i).DataType)
SignalNameOut = can_signal_group_Struct(i).SignalName{j};
SignalDataTypeOut = can_signal_group_Struct(i).DataType{j};
if isempty(SignalDataTypeOut)
SignalDataTypeOut = 'uint8';
end
if j == 1
outputParameter_str = 'saveVarsTmp{1} = Simulink.BusElement;\n';
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}.Name = ''',SignalNameOut,''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}.Complexity = ''','real',''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = 'saveVarsTmp{1}.Dimensions = 1;\n';
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}.DataType = ''',SignalDataTypeOut,''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = 'saveVarsTmp{1}.Min = [];\n';
fprintf(fid,outputParameter_str);
outputParameter_str = 'saveVarsTmp{1}.Max = [];\n';
fprintf(fid,outputParameter_str);
outputParameter_str = 'saveVarsTmp{1}.DimensionsMode = ''Fixed'';\n';
fprintf(fid,outputParameter_str);
outputParameter_str = 'saveVarsTmp{1}.SamplingMode = ''Sample based'';\n';
fprintf(fid,outputParameter_str);
outputParameter_str = 'saveVarsTmp{1}.DocUnits = '''';\n';
fprintf(fid,outputParameter_str);
outputParameter_str = 'saveVarsTmp{1}.Description = '''';\n';
fprintf(fid,outputParameter_str);
else
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)',' = Simulink.BusElement;\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.Name = ''',SignalNameOut,''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.Complexity = ''','real',''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.Dimensions = 1;\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.DataType = ''',SignalDataTypeOut,''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.Min = [];\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.Max = [];\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.DimensionsMode = ''','Fixed',''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.SamplingMode = ''','Sample based',''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.DocUnits = '''';\n');
fprintf(fid,outputParameter_str);
outputParameter_str = strcat('saveVarsTmp{1}(',num2str(j),', 1)','.Description = '''';\n');
fprintf(fid,outputParameter_str);
end
if j == length(can_signal_group_Struct(i).DataType)
outputParameter_str = strcat(GroupName,'.Elements = saveVarsTmp{1};\n');
fprintf(fid,outputParameter_str);
outputParameter_str = 'clear saveVarsTmp;\n';
fprintf(fid,outputParameter_str);
end
end
fprintf(fid,'\n');
end
此处我们只设定了组名称,信号名称,信号数据类型,其他的属性都是按默认值来的。
需要注意的是HeaderFile,因为我们使用Autosar代码生成,所以定义的结构体的头文件应该设置为Rte_Type.h,否则后面在生成代码时会报错找不到数据类型定义。
自动生成的m文件示例如下:
BrkPedlTrvl = Simulink.Bus;
BrkPedlTrvl.Description = '';
BrkPedlTrvl.DataScope = 'Auto';
BrkPedlTrvl.HeaderFile = 'Rte_Type.h';
BrkPedlTrvl.Alignment = -1;
BrkPedlTrvl.PreserveElementDimensions = false;
saveVarsTmp{1} = Simulink.BusElement;
saveVarsTmp{1}.Name = 'BrkPedlTrvlAct';
saveVarsTmp{1}.Complexity = 'real';
saveVarsTmp{1}.Dimensions = 1;
saveVarsTmp{1}.DataType = 'uint16';
saveVarsTmp{1}.Min = [];
saveVarsTmp{1}.Max = [];
saveVarsTmp{1}.DimensionsMode = 'Fixed';
saveVarsTmp{1}.SamplingMode = 'Sample based';
saveVarsTmp{1}.DocUnits = '';
saveVarsTmp{1}.Description = '';
saveVarsTmp{1}(2, 1) = Simulink.BusElement;
saveVarsTmp{1}(2, 1).Name = 'BrkPedlTrvlChks';
saveVarsTmp{1}(2, 1).Complexity = 'real';
saveVarsTmp{1}(2, 1).Dimensions = 1;
saveVarsTmp{1}(2, 1).DataType = 'uint8';
saveVarsTmp{1}(2, 1).Min = [];
saveVarsTmp{1}(2, 1).Max = [];
saveVarsTmp{1}(2, 1).DimensionsMode = 'Fixed';
saveVarsTmp{1}(2, 1).SamplingMode = 'Sample based';
saveVarsTmp{1}(2, 1).DocUnits = '';
saveVarsTmp{1}(2, 1).Description = '';
....
运行该m文件,即可得到对应的结构体定义,示例如下:
在之前的文章中介绍过S/R接口的生成和mapping,此处不再详细介绍。
需要注意的是结构体类型在定义数据类型时的格式为:Bus: xxx,所以在创建Input模块时需要注意下
GroupDataTypeStr = strcat('Bus:',32,can_signal_group_Struct(i).GroupName);
handle = add_block('simulink/Sources/In1',RTEInput_ParameterName,'OutDataTypeStr',GroupDataTypeStr,...
'PortDimensions',num2str(1),'BusOutputAsStruct','on');
此处对于BusOutputAsStruct属性,需要配置为on,否则生成代码会报错
自动生成Port及mapping
编译生成arxml
导入Autosar工具中
通过脚本实现Group类型的Port自动创建,可以节约一定的开发时间,对于重复性较高的工作,建议开发脚本实现半自动或自动化。