• 基于DBC Signal Group生成Autosar SR接口(1)


    前言

    在开发Autosar CAN通信模块时,对于Signal Group需要建立对应的Interface,其中的数据类型实际是一个结构体,包含Group中的Signal的数据类型定义。手动建立比较费时间,本文介绍利用Matlab脚本自动生成SignalGroup对应的Interface

    实现方法

    主要方法通过正则表达式提取DBC中的SignalGroup,生成BUS类型的m脚本,再通过Matlab脚本建立Simulnk模型及端口,建立RTE Port及mapping最后编译生成Arxml。

    结构体在Simulink中的定义

    在生成BUS之前,首先得清楚BUS的m文件定义

    手动建立一个Simulink Bus的数据类型,如下所示:


    导出m文件,如下所示:

    Bus = Simulink.Bus;
    Bus.Description = '';
    Bus.DataScope = 'Auto';
    Bus.HeaderFile = '';
    Bus.Alignment = -1;
    Bus.PreserveElementDimensions = false;
    saveVarsTmp{1} = Simulink.BusElement;
    saveVarsTmp{1}.Name = 'a';
    saveVarsTmp{1}.Complexity = 'real';
    saveVarsTmp{1}.Dimensions = 1;
    saveVarsTmp{1}.DataType = 'single';
    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 = 'a1';
    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 = '';
    saveVarsTmp{1}(3, 1) = Simulink.BusElement;
    saveVarsTmp{1}(3, 1).Name = 'a2';
    saveVarsTmp{1}(3, 1).Complexity = 'real';
    saveVarsTmp{1}(3, 1).Dimensions = 1;
    saveVarsTmp{1}(3, 1).DataType = 'single';
    saveVarsTmp{1}(3, 1).Min = [];
    saveVarsTmp{1}(3, 1).Max = [];
    saveVarsTmp{1}(3, 1).DimensionsMode = 'Fixed';
    saveVarsTmp{1}(3, 1).SamplingMode = 'Sample based';
    saveVarsTmp{1}(3, 1).DocUnits = '';
    saveVarsTmp{1}(3, 1).Description = '';
    Bus.Elements = saveVarsTmp{1};
    clear saveVarsTmp;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    上面的BUS定义了三个数据,对于需要生成的M文件,主要关注的是数据的排列序号,第二和第三个数据定义以saveVarsTmp{1}(x, 1)开头,然后是数据的NameDataType,此处我们没有考虑Dimensions为多维(DBC中都是一维)

    此处需要留意的是HeaderFile这个属性,在后面会着重提

    SignalGroup提取

    Matlab有解析DBC的API函数,但可惜的是,不能解析出SignalGroup,只能解析出Message和其中的Signal。不过,利用正则表达式,提取SiganlGroup也不是难事~

    记事本打开DBC,查找Group,可以找到SignalGroup的定义,如下所示:

    SIG_GROUP_ 258 TestGroupName 1 : TestGroupSignal1 TestGroupSignal2 TestGroupSignal3 TestGroupSignal4;
    
    
    • 1
    • 2

    上面的定义中,数字表示的是Group所在的message id,后面跟的是Group的名称,再后面跟的是1(目前遇到的都是1,没有查过具体的定义,估计是和信号组复用相关的),再后面跟的就是Signal,最后以分号结尾。

    正则表达式提取文本中的SignalGroup信息,m脚本如下:

    fid = fopen(dbcfile_name,'r');
    file_code = {''};
    ct = 1;
    while ~feof(fid)
        file_code(ct,1)={fgets(fid)};
        ct=ct+1;        
    end
    can_signal_group_pattern1 = '(?<=SIG_GROUP_ ).+';%提取信号组信息
    can_signal_group  = regexp(file_code,can_signal_group_pattern1,'match');%取信号组信息
    can_signal_group(cellfun(@isempty,can_signal_group))=[];%去除空字符串所在行
    for i = 1:length(can_signal_group) 
        can_signal_group_name{i} =  regexp(can_signal_group{i},'\S+','match');
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    此处can_signal_group_name包含Group中的元素,按空格分开,例如第一个为ID,第二个为GroupName,第三个为1,第四个为":",后面跟的是Signal

    GroupStruct = struct('GroupName',{}, 'ID',{} ,...
        'SignalName',{},'DataType',{});
    for i = 1:length(can_signal_group_name) 
        can_signal_group_Struct(i).GroupName =  can_signal_group_name{i}{1}{2};
        can_signal_group_Struct(i).ID =  can_signal_group_name{i}{1}{1};
        can_signal_group_pattern_fen = '.+(?=;)';%用来去除最后一个分号
        can_signal_group_name{i}{1}{length(can_signal_group_name{i}{1})} = regexp(can_signal_group_name{i}{1}{length(can_signal_group_name{i}{1})},can_signal_group_pattern_fen,'match');
        can_signal_group_name{i}{1}{length(can_signal_group_name{i}{1})} = can_signal_group_name{i}{1}{length(can_signal_group_name{i}{1})}{1};
        for j = 5:length(can_signal_group_name{i}{1})
            can_signal_group_Struct(i).SignalName{j-4} = can_signal_group_name{i}{1}{j};
        end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    此处我们已经提取出了SignalGroup中的GroupName,ID,及其中的SignalName。其中还有一个关键信息,就是Signal的数据类型。此处我们利用Matlab自带的函数提取Signal的信息

    db = canDatabase(dbcfile_name);
    for i = 1:length(can_signal_group_Struct) 
        for j = 1:length(can_signal_group_Struct(i).SignalName) 
            for a = 1:length(db.MessageInfo)
                for b = 1:length(db.MessageInfo(a).SignalInfo)
                    if(strncmp(can_signal_group_Struct(i).SignalName{j},db.MessageInfo(a).SignalInfo(b).Name,32))
                        can_signal_group_Struct(i).DataType{j} = db.MessageInfo(a).SignalInfo(b).Class;
                        a=1;
                        b=1;
                        break;
                    end
                    if(i == length(can_signal_group_Struct) )
                        break;
                    end
                end
                if(i == length(can_signal_group_Struct) )
                    break;
                end
            end
            if(i == length(can_signal_group_Struct) )
                break;
            end
        end
        if(i == length(can_signal_group_Struct) )
            break;
        end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    判断Messag的SignalName和Group中的SignalName是否一致,此处只取前32个字节,因为太长会导致DBC报错,Group中的Name也不会全


    到此,我们已经提取了生成BUS所需的主要信号。

    接下来就是生成M文件,及后面的生成接口模型了,下一次再说吧。

    关于HeaderFile,主要是在生成Autosar文件的时候,没有配置该属性的话,会报错找不到对应的Type

    总结

    本文介绍了DBC中Signal Group的提取,在没接触Autosar软件时,没有用过SignalGroup,Signal成组之后,一方面可以更好的管理,另一方面,为E2E也提供了载体。

  • 相关阅读:
    编程技巧│php 自定义安装扩展
    SSM - Springboot - MyBatis-Plus 全栈体系(二十六)
    项目经理之如何组建跨部门项目团队
    SpringBoot多文件配置,加载顺序与位置
    AE调试(人脸场景)
    Redis集群
    Github又悄悄升级了,这次的变化是大文件的存储方式
    Kotlin高仿微信-第35篇-支付-二维码收款(二维码)
    华为HCIA(五)
    128. SAP UI5 智能控件 Smart Controls 的初步认识
  • 原文地址:https://blog.csdn.net/weixin_49000276/article/details/133686674