Flexray,Lin添加

This commit is contained in:
“hsc”
2026-08-05 11:53:51 +08:00
parent 66bb6d36ba
commit 5a565f7361
11 changed files with 1152 additions and 0 deletions
+248
View File
@@ -0,0 +1,248 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json.Serialization;
using TSMaster;
namespace TSMasterFlexRay
{
/// <summary>
/// FlexRay 网络(Cluster
/// </summary>
public struct flexray_network
{
[JsonInclude]
public string network_name;
[JsonInclude]
public flexray_node[] flexray_nodes;
}
/// <summary>
/// FlexRay 节点(ECU
/// </summary>
public struct flexray_node
{
[JsonInclude]
public string node_name;
[JsonInclude]
public flexray_message[] tx_flexray_Messages;
[JsonInclude]
public flexray_message[] rx_flexray_Messages;
}
/// <summary>
/// FlexRay 帧(Frame
/// </summary>
public struct flexray_message
{
[JsonInclude]
public string message_name;
[JsonInclude]
public int slot_id;
[JsonInclude]
public int channel_mask;
[JsonInclude]
public int base_cycle;
[JsonInclude]
public int rep_cycle;
[JsonInclude]
public bool is_startup_frame;
[JsonInclude]
public int dlc;
[JsonInclude]
public string[] signals;
}
/// <summary>
/// FlexRay 解码后的信号信息
/// </summary>
public struct FlexRaySignal
{
/// <summary>信号名称</summary>
public string name;
/// <summary>起始位</summary>
public int start_bit;
/// <summary>长度(bit</summary>
public int length;
/// <summary>因子</summary>
public double factor;
/// <summary>偏移</summary>
public double offset;
/// <summary>初始值</summary>
public double init_value;
/// <summary>信号类型</summary>
public TSignalType signal_type;
/// <summary>字节序(true=小端)</summary>
public bool is_intel;
}
/// <summary>
/// FlexRay 解码后的报文信息
/// </summary>
public class FlexRayDBMessage
{
/// <summary>时隙号</summary>
public int nSlotId;
/// <summary>周期号</summary>
public int nCycleNumber;
/// <summary>通道掩码</summary>
public int nChannelMask;
/// <summary>有效负载长度</summary>
public int nDataLength;
/// <summary>数据</summary>
public byte[] Data = Array.Empty<byte>();
}
public class FlexRayDBParse
{
private static FlexRayDBParse? _instance;
/// <summary>单例实例</summary>
public static FlexRayDBParse Instance => _instance ??= new FlexRayDBParse();
/// <summary>最大通道数(等于 MsgDatabase 的维度)</summary>
public int MaxChannels => MsgDatabase.Count;
/// <summary>
/// FlexRay 报文数据库(按通道索引,每个通道包含该通道上所有帧)。
/// </summary>
public static List<List<flexray_message>> MsgDatabase { get; set; } =
[.. Enumerable.Range(0, 12).Select(_ => new List<flexray_message>())];
/// <summary>FlexRay 网络拓扑(Cluster/ECU/Frame/Signal</summary>
public static flexray_network Network;
/// <summary>
/// 解析指定索引的 FlexRay 数据库,填充 MsgDatabase 和 Network。
/// FlexRay 数据库由工程加载,通过 tsdb_get_flexray_db_count 获取数量。
/// </summary>
/// <param name="dbIndex">数据库索引(0-based</param>
/// <param name="channel">映射的通道号</param>
public static void parse(int dbIndex, int channel)
{
int ASignalCount = 0;
int AFrameCount = 0;
int AECUcount = 0;
long ASupportMask = 0;
long AFlags = 0;
IntPtr temp1 = IntPtr.Zero;
IntPtr temp2 = IntPtr.Zero;
// 1. 获取 Cluster 属性
int ret = TsMasterApi.tsdb_get_flexray_db_properties_by_index_verbose(
dbIndex, ref ASignalCount, ref AFrameCount, ref AECUcount,
ref ASupportMask, ref AFlags, ref temp1, ref temp2);
string clusterName = Marshal.PtrToStringAnsi(temp1) ?? "";
Network = new flexray_network
{
network_name = clusterName,
flexray_nodes = new flexray_node[AECUcount]
};
// 2. 遍历所有 ECU
for (int i = 0; i < AECUcount; i++)
{
int ATXFramecount = 0;
int ARXFramecount = 0;
TsMasterApi.tsdb_get_flexray_ecu_properties_by_index_verbose(
dbIndex, i, ref ATXFramecount, ref ARXFramecount, ref temp1, ref temp2);
string ecuName = Marshal.PtrToStringAnsi(temp1) ?? "";
Network.flexray_nodes[i].node_name = ecuName;
Network.flexray_nodes[i].tx_flexray_Messages = new flexray_message[ATXFramecount];
Network.flexray_nodes[i].rx_flexray_Messages = new flexray_message[ARXFramecount];
// TX Frame
for (int tx = 0; tx < ATXFramecount; tx++)
{
var msg = ParseFrame(dbIndex, i, tx, true);
Network.flexray_nodes[i].tx_flexray_Messages[tx] = msg;
MsgDatabase[channel].Add(msg);
}
// RX Frame
for (int rx = 0; rx < ARXFramecount; rx++)
{
var msg = ParseFrame(dbIndex, i, rx, false);
Network.flexray_nodes[i].rx_flexray_Messages[rx] = msg;
}
}
MsgDatabase[channel].Sort((a, b) => a.slot_id.CompareTo(b.slot_id));
}
/// <summary>
/// 解析单帧属性(TX 或 RX
/// </summary>
private static flexray_message ParseFrame(int dbIndex, int ecuIndex, int frameIndex, bool isTx)
{
int AFRChannelMask = 0;
int AFRBaseCycle = 0;
int ARepCycle = 0;
bool isStartupFrame = false;
int ASlotID = 0;
long CycleMask = 0;
int AFRSignalCount = 0;
int AFRDLC = 0;
IntPtr temp1 = IntPtr.Zero;
IntPtr temp2 = IntPtr.Zero;
TsMasterApi.tsdb_get_flexray_frame_properties_by_index_verbose(
dbIndex, ecuIndex, frameIndex, isTx,
ref AFRChannelMask, ref AFRBaseCycle, ref ARepCycle, ref isStartupFrame,
ref ASlotID, ref CycleMask, ref AFRSignalCount, ref AFRDLC,
ref temp1, ref temp2);
string frameName = Marshal.PtrToStringAnsi(temp1) ?? "";
var msg = new flexray_message
{
message_name = frameName,
slot_id = ASlotID,
channel_mask = AFRChannelMask,
base_cycle = AFRBaseCycle,
rep_cycle = ARepCycle,
is_startup_frame = isStartupFrame,
dlc = AFRDLC,
signals = new string[AFRSignalCount]
};
// 遍历信号
for (int s = 0; s < AFRSignalCount; s++)
{
TSignalType Asignaltype = (TSignalType)0;
TFlexRayCompuMethod ACompuMethod = (TFlexRayCompuMethod)0;
bool AIsIntel = false;
int AStartBit = 0;
int AUpdateBit = 0;
int ALength = 0;
double AFactor = 0;
double AOffset = 0;
double AInitValue = 0;
TsMasterApi.tsdb_get_flexray_signal_properties_by_index_verbose(
dbIndex, ecuIndex, frameIndex, s, isTx,
ref Asignaltype, ref ACompuMethod, ref AIsIntel,
ref AStartBit, ref AUpdateBit, ref ALength,
ref AFactor, ref AOffset, ref AInitValue,
ref temp1, ref temp2);
string sigName = Marshal.PtrToStringAnsi(temp1) ?? "";
msg.signals[s] = sigName;
}
return msg;
}
/// <summary>
/// 解析网络拓扑(仅填充 Network,不写入 MsgDatabase
/// </summary>
public static void rbs_parse(int dbIndex, int channel)
{
// parse 已同时填充 Network 和 MsgDatabase,此处保持与 CAN 一致的接口
parse(dbIndex, channel);
}
}
}