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
{
///
/// FlexRay 网络(Cluster)
///
public struct flexray_network
{
[JsonInclude]
public string network_name;
[JsonInclude]
public flexray_node[] flexray_nodes;
}
///
/// FlexRay 节点(ECU)
///
public struct flexray_node
{
[JsonInclude]
public string node_name;
[JsonInclude]
public flexray_message[] tx_flexray_Messages;
[JsonInclude]
public flexray_message[] rx_flexray_Messages;
}
///
/// FlexRay 帧(Frame)
///
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;
}
///
/// FlexRay 解码后的信号信息
///
public struct FlexRaySignal
{
/// 信号名称
public string name;
/// 起始位
public int start_bit;
/// 长度(bit)
public int length;
/// 因子
public double factor;
/// 偏移
public double offset;
/// 初始值
public double init_value;
/// 信号类型
public TSignalType signal_type;
/// 字节序(true=小端)
public bool is_intel;
}
///
/// FlexRay 解码后的报文信息
///
public class FlexRayDBMessage
{
/// 时隙号
public int nSlotId;
/// 周期号
public int nCycleNumber;
/// 通道掩码
public int nChannelMask;
/// 有效负载长度
public int nDataLength;
/// 数据
public byte[] Data = Array.Empty();
}
public class FlexRayDBParse
{
private static FlexRayDBParse? _instance;
/// 单例实例
public static FlexRayDBParse Instance => _instance ??= new FlexRayDBParse();
/// 最大通道数(等于 MsgDatabase 的维度)
public int MaxChannels => MsgDatabase.Count;
///
/// FlexRay 报文数据库(按通道索引,每个通道包含该通道上所有帧)。
///
public static List> MsgDatabase { get; set; } =
[.. Enumerable.Range(0, 12).Select(_ => new List())];
/// FlexRay 网络拓扑(Cluster/ECU/Frame/Signal)
public static flexray_network Network;
///
/// 解析指定索引的 FlexRay 数据库,填充 MsgDatabase 和 Network。
/// FlexRay 数据库由工程加载,通过 tsdb_get_flexray_db_count 获取数量。
///
/// 数据库索引(0-based)
/// 映射的通道号
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));
}
///
/// 解析单帧属性(TX 或 RX)
///
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;
}
///
/// 解析网络拓扑(仅填充 Network,不写入 MsgDatabase)
///
public static void rbs_parse(int dbIndex, int channel)
{
// parse 已同时填充 Network 和 MsgDatabase,此处保持与 CAN 一致的接口
parse(dbIndex, channel);
}
}
}