在 CAN 通信中使用 ARXML 文件
以下示例说明如何使用存储在 ARXML 文件中的信息创建、接收和处理报文。
打开 ARXML 文件
从 ARXML 文件在工作区中创建一个数据库。该数据库包含有关 ARXML 文件的元数据和结构体信息。
db = arxmlDatabase("demoFile.arxml")db =
Database with properties:
Name: "demoFile.arxml"
Path: "/tmp/Bdoc26a_3233028_2243768/tp6061b4c6/vnt-ex83636057/demoFile.arxml"
CAN: [1×1 vnt.arxml.protocol.CAN]
请检查 Frame 属性,以查看此文件中定义的所有报文的名称。
db.CAN.Frame
ans=2×9 table
Name Path ID Extended StartBit Length ByteOrder PDU FrameTriggering
______________ _______________________________ ____ ________ ________ ______ _______________________ ________________________________ ___________________
"EngineMsg" "/MathWorks/FRAME/EngineMsg" 1000 false 0 8 mostSignificantByteLast /MathWorks/PDUS/Engine_PDU "FrameTriggering_1"
"VehicleState" "/MathWorks/FRAME/VehicleState" 1001 true 0 4 mostSignificantByteLast /MathWorks/PDUS/VehicleState_PDU "FrameTriggering_2"
查看 PDU 信息
在表中,查看 EngineMsg 的协议数据单元 (PDU) 信息,包括 PDU 起始位、数据长度和信号列表。仅支持 ISignalIPDU。
ISignalIPDUTable = db.CAN.PDU.ISignalIPDU;
EnginPDU = ISignalIPDUTable(ISignalIPDUTable.Name == "Engine_PDU", :)EnginPDU=1×6 table
Name Frame ISignal StartBit Length ByteOrder
____________ __________________________ ___________ ________ ______ _______________________
"Engine_PDU" /MathWorks/FRAME/EngineMsg {4×5 table} 0 8 mostSignificantByteLast
查看信号元数据
有两种方法可以查看信号信息。在 ISignalIPDU 表中查看特定 PDU 的信号的基本映射信息。
EnginPDU.ISignal{1}ans=4×5 table
Name StartBit Length ByteOrder BaseType
____________________ ________ ______ _______________________ ____________
"VehicleSpeed" 0 8 mostSignificantByteLast {1×1 struct}
"TransmissionStatus" 8 8 mostSignificantByteLast {1×1 struct}
"GPSSpeed" 16 8 mostSignificantByteLast {1×1 struct}
"EngineSpeed" 24 32 mostSignificantByteLast {1×1 struct}
您也可以在 ISignal 表中查看信号信息,该表提供更多详细信息,包括单位、compuMethod、baseType、systemSignal 引用等。
db.CAN.ISignal
ans=5×9 table
Name CompuMethod StartBit Length ByteOrder BaseType Unit PDU SystemSignal
____________________ _________________________ ________ ______ _______________________ ____________ ____ ________________________________ _____________________________________________________
"EngineSpeed" 1×1 vnt.arxml.CompuMethod 24 32 mostSignificantByteLast {1×1 struct} rpm /MathWorks/PDUS/Engine_PDU "/MathWorks/SYSTEM_SIGNALS/EngineSpeed_System"
"GPSSpeed" 1×1 vnt.arxml.CompuMethod 16 8 mostSignificantByteLast {1×1 struct} rpm /MathWorks/PDUS/Engine_PDU "/MathWorks/SYSTEM_SIGNALS/GPSSpeed_System"
"Ignition" 1×1 vnt.arxml.CompuMethod 0 2 mostSignificantByteLast {1×1 struct} rpm /MathWorks/PDUS/VehicleState_PDU "/MathWorks/SYSTEM_SIGNALS/Ignition_System"
"TransmissionStatus" 1×1 vnt.arxml.CompuMethod 8 8 mostSignificantByteLast {1×1 struct} mph /MathWorks/PDUS/Engine_PDU "/MathWorks/SYSTEM_SIGNALS/TransmissionStatus_System"
"VehicleSpeed" 1×1 vnt.arxml.CompuMethod 0 8 mostSignificantByteLast {1×1 struct} rpm /MathWorks/PDUS/Engine_PDU "/MathWorks/SYSTEM_SIGNALS/VehicleSpeed_System"
使用数据库定义创建报文
通过指定要应用数据库定义的数据库和报文名称 EngineMsg 来创建新报文。
msgEngine = canMessage(db, "EngineMsg")msgEngine =
Message with properties:
Message Identification
ProtocolMode: 'CAN'
ID: 1000
Extended: 0
Name: 'EngineMsg'
Data Details
Timestamp: 0
Data: [0 0 0 0 0 0 0 0]
Signals: [1×1 struct]
Length: 8
Protocol Flags
Error: 0
Remote: 0
Other Information
Database: [1×1 vnt.arxml.Database]
UserData: []
查看信号值
查看 Signals 属性以查看此报文的信号值。您可以直接对这些信号进行写入和读取,以打包和解包报文中的数据。EngineMsg 包括 VehicleSpeed、TransmissionStatus、GPSSpeed 和 EngineSpeed。VehicleSpeed、TransmissionStatus 和 EngineSpeed 是数值。TransmissionStatus 是枚举类型,其值可以是 'P'、'N'、'R' 或 'D'。枚举值作为文本输出,使用在 ARXML 文件中定义的文本类别 CompuMethod(例如 TEXTTABLE)从原始 CAN 报文转换而来。
msgEngine.Signals
ans = struct with fields:
VehicleSpeed: 0
TransmissionStatus: 'P'
GPSSpeed: 0
EngineSpeed: 0
更改信号信息
将信号 TransmissionStatus 的值从 'P'(泊车)更改为 'N'(空档)。
msgEngine.Signals.TransmissionStatus = 'N'; 读回信号值以验证 TransmissionStatus 已用新值更新。
msgEngine.Signals
ans = struct with fields:
VehicleSpeed: 0
TransmissionStatus: 'N'
GPSSpeed: 0
EngineSpeed: 0
当值直接写入信号时,它会转换、缩放,并使用数据库定义打包到报文数据中。请注意在向 EngineSpeed 信号写入新值后,Data 属性中的值变化。
msgEngine.Signals.EngineSpeed = 5500; msgEngine.Signals
ans = struct with fields:
VehicleSpeed: 0
TransmissionStatus: 'N'
GPSSpeed: 0
EngineSpeed: 5500
接收具有数据库信息的报文
要自动将数据库定义应用于传入报文,请将数据库连接到接收报文的 CAN 通道。数据库仅解码那些已定义的报文。所有其他报文都以其原始形式接收。
rxCh = canChannel("MathWorks", "Virtual 1", 2); rxCh.Database = db
rxCh =
Channel with properties:
Device Information
DeviceVendor: 'MathWorks'
Device: 'Virtual 1'
DeviceChannelIndex: 2
DeviceSerialNumber: 0
ProtocolMode: 'CAN'
Status Information
Running: 0
MessagesAvailable: 0
MessagesReceived: 0
MessagesTransmitted: 0
InitializationAccess: 1
InitialTimestamp: [0×0 datetime]
FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All'
Channel Information
BusStatus: 'N/A'
SilentMode: 0
TransceiverName: 'N/A'
TransceiverState: 'N/A'
ReceiveErrorCount: 0
TransmitErrorCount: 0
BusSpeed: 500000
SJW: []
TSEG1: []
TSEG2: []
NumOfSamples: []
Other Information
Database: [1×1 vnt.arxml.Database]
UserData: []
接收报文
启动通道,生成一些报文流,然后通过物理报文解码来接收报文。
start(rxCh); generateCANMsgsARXML(); rxMsg = receive(rxCh, Inf, "OutputFormat", "timetable"); rxMsg(1:15, :)
ans=15×8 timetable
Time ID Extended Name Data Length Signals Error Remote
___________ ____ ________ ________________ ______________________ ______ ____________ _____ ______
0.15584 sec 1000 false {'EngineMsg' } {[ 0 3 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.15585 sec 1001 true {'VehicleState'} {[ 0 0 0 0]} 4 {1×1 struct} false false
0.40585 sec 1000 false {'EngineMsg' } {[68 3 102 0 0 0 0 0]} 8 {1×1 struct} false false
0.65586 sec 1000 false {'EngineMsg' } {[ 66 3 90 0 0 0 0 0]} 8 {1×1 struct} false false
0.65586 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
0.90586 sec 1000 false {'EngineMsg' } {[61 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.1559 sec 1000 false {'EngineMsg' } {[ 68 3 91 0 0 0 0 0]} 8 {1×1 struct} false false
1.1559 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
1.4059 sec 1000 false {'EngineMsg' } {[67 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.6559 sec 1000 false {'EngineMsg' } {[68 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.6559 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
1.9059 sec 1000 false {'EngineMsg' } {[ 67 3 94 0 0 0 0 0]} 8 {1×1 struct} false false
2.1559 sec 1000 false {'EngineMsg' } {[ 67 3 89 0 0 0 0 0]} 8 {1×1 struct} false false
2.1559 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
2.4059 sec 1000 false {'EngineMsg' } {[ 66 3 93 0 0 0 0 0]} 8 {1×1 struct} false false
停止接收通道并将其从工作区中清除。
stop(rxCh);
clear rxCh检查收到的报文
检查收到的报文以查看应用的数据库解码。
rxMsg(10, :)
ans=1×8 timetable
Time ID Extended Name Data Length Signals Error Remote
__________ ____ ________ _____________ ______________________ ______ ____________ _____ ______
1.6559 sec 1000 false {'EngineMsg'} {[68 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
rxMsg.Signals{10}ans = struct with fields:
VehicleSpeed: 68
TransmissionStatus: 'D'
GPSSpeed: 69.3333
EngineSpeed: 0
提取指定报文的所有实例
提取报文 EngineMsg 的所有实例。
allmsgEngine = rxMsg("EngineMsg" == rxMsg.Name, :);
allmsgEngine(1:15, :)ans=15×8 timetable
Time ID Extended Name Data Length Signals Error Remote
___________ ____ ________ _____________ ______________________ ______ ____________ _____ ______
0.15584 sec 1000 false {'EngineMsg'} {[ 0 3 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.40585 sec 1000 false {'EngineMsg'} {[68 3 102 0 0 0 0 0]} 8 {1×1 struct} false false
0.65586 sec 1000 false {'EngineMsg'} {[ 66 3 90 0 0 0 0 0]} 8 {1×1 struct} false false
0.90586 sec 1000 false {'EngineMsg'} {[61 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.1559 sec 1000 false {'EngineMsg'} {[ 68 3 91 0 0 0 0 0]} 8 {1×1 struct} false false
1.4059 sec 1000 false {'EngineMsg'} {[67 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.6559 sec 1000 false {'EngineMsg'} {[68 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.9059 sec 1000 false {'EngineMsg'} {[ 67 3 94 0 0 0 0 0]} 8 {1×1 struct} false false
2.1559 sec 1000 false {'EngineMsg'} {[ 67 3 89 0 0 0 0 0]} 8 {1×1 struct} false false
2.4059 sec 1000 false {'EngineMsg'} {[ 66 3 93 0 0 0 0 0]} 8 {1×1 struct} false false
2.6559 sec 1000 false {'EngineMsg'} {[ 64 3 94 0 0 0 0 0]} 8 {1×1 struct} false false
2.9059 sec 1000 false {'EngineMsg'} {[ 61 3 96 0 0 0 0 0]} 8 {1×1 struct} false false
3.1559 sec 1000 false {'EngineMsg'} {[67 3 100 0 0 0 0 0]} 8 {1×1 struct} false false
3.4059 sec 1000 false {'EngineMsg'} {[ 66 3 91 0 0 0 0 0]} 8 {1×1 struct} false false
3.6559 sec 1000 false {'EngineMsg'} {[ 65 3 92 0 0 0 0 0]} 8 {1×1 struct} false false
绘制物理信号值
使用 canSignalTimetable 将报文 EngineMsg 中的信号数据重新打包为一个信号时间表。
signalTimetable = canSignalTimetable(rxMsg, "EngineMsg");
signalTimetable(1:15, 1:3)ans=15×3 timetable
Time VehicleSpeed TransmissionStatus GPSSpeed
___________ ____________ __________________ ________
0.15584 sec 0 "D" 0
0.40585 sec 68 "D" 68.667
0.65586 sec 66 "D" 60.667
0.90586 sec 61 "D" 69.333
1.1559 sec 68 "D" 61.333
1.4059 sec 67 "D" 69.333
1.6559 sec 68 "D" 69.333
1.9059 sec 67 "D" 63.333
2.1559 sec 67 "D" 60
2.4059 sec 66 "D" 62.667
2.6559 sec 64 "D" 63.333
2.9059 sec 61 "D" 64.667
3.1559 sec 67 "D" 67.333
3.4059 sec 66 "D" 61.333
3.6559 sec 65 "D" 62
绘制信号 VehicleSpeed 随时间变化的值。
plot(signalTimetable.Time, signalTimetable.VehicleSpeed) title("Vehicle Speed from EngineMsg", "FontWeight", "bold") xlabel("Timestamp") ylabel("Vehicle Speed")

关闭 ARXML 文件
通过从工作区中清除数据库变量,关闭对该 ARXML 文件的访问。
clear db