using Common.Attributes;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.Json;
using TSMaster;
namespace CAN驱动
{
[BOBCommand]
public class 同星驱动类
{
public static event Action ConnectEvent;
public static event Action DisConnectEvent;
public static bool ConnectFlag { get; set; } = false;
///
/// 初始化CAN驱动
///
///
///
///
[Browsable(false)]
public static int Init(string ProjectName, string? filePath = null)
{
if (string.IsNullOrEmpty(filePath))
{
return TsMasterApi.initialize_lib_tsmaster(ProjectName);
}
else
{
return TsMasterApi.initialize_lib_tsmaster_with_project(ProjectName, Path.GetFullPath(filePath));
}
}
///
/// 释放CAN驱动
///
[Browsable(false)]
public static void Release()
{
TsMasterApi.finalize_lib_tsmaster();
}
public static int obj = 0;
public static TCANFDQueueEvent_Win32 listener;
[Browsable(false)]
public static int RegisterListener(TCANFDQueueEvent_Win32 listenEvent)
{
listener = listenEvent;
var re = TsMasterApi.tsapp_register_event_canfd(ref obj, listener);
Debug.Assert(re == 0);
return re;
}
[Browsable(false)]
public static int UnRegisterListener(TCANFDQueueEvent_Win32 listenEvent = null)
{
if (listenEvent is not null)
{
listener = listenEvent;
}
var re = TsMasterApi.tsapp_unregister_event_canfd(ref obj, listener);
Debug.Assert(re == 0);
return re;
}
///
/// 连接
///
///
public static int Connect()
{
var re = TsMasterApi.tsapp_connect();
if (re == 0)
{
re = TsMasterApi.tscom_can_rbs_start();
if (re == 0)
{
ConnectFlag = true;
Task.Run(() => ConnectEvent?.Invoke());
}
else
{
Debug.WriteLine($"CAN_RBS启动失败,错误代码:{re}");
}
}
else
{
Debug.WriteLine($"CAN连接失败,错误代码:{re}");
return re;
}
return re;
}
///
/// 断开
///
///
public static int DisConnect()
{
var re = TsMasterApi.tsapp_disconnect();
//Debug.Assert(re == 0);
if (re == 0)
{
ConnectFlag = false;
Task.Run(() => DisConnectEvent?.Invoke());
}
else
{
Debug.WriteLine($"断开CAN连接失败,错误代码:{re}");
}
return re;
}
///
/// 加载DBC
///
///
///
///
///
[Browsable(false)]
public static int LoadDBC(string filePath, int[] channel, out uint databaseID)
{
databaseID = 0;
var re = TsMasterApi.tsdb_load_can_db(Path.GetFullPath(filePath), string.Join(",", channel), ref databaseID);
foreach (var item in channel)
{
DBCParse.parse(databaseID, item);
DBCParse.rbs_parse(databaseID, item);
}
return re;
}
///
/// 卸载DBC
///
///
///
[Browsable(false)]
public static int UnLoadDBC(uint? databaseID = null)
{
if (databaseID == null)
{
return TsMasterApi.tsdb_unload_can_dbs();
}
else
{
return TsMasterApi.tsdb_unload_can_db(databaseID.Value);
}
}
///
/// 开始记录日志
///
///
///
public static int StartLogging(string filePath)
{
return TsMasterApi.tsapp_start_logging(Path.GetFullPath(filePath));
}
///
/// 结束记录日志
///
///
public static int StopLogging()
{
return TsMasterApi.tsapp_stop_logging();
}
///
/// 弹出通道映射窗口
///
///
///
[Browsable(false)]
public static int ShowChannelMappingWindow(bool isWait = false)
{
return TsMasterApi.tsapp_show_tsmaster_window("Hardware", isWait);
}
///
/// 获取信号值
///
///
///
///
///
public static double GetSignalValue(byte channel, string AMsgName, string ASgnName)
{
double value = double.NaN;
var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
var re = TsMasterApi.tsdb_get_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, ref value);
return value;
}
///
/// 获取信号值
///
///
///
///
///
///
[Browsable(false)]
public static int GetSignalValue(byte channel, string AMsgName, string ASgnName, ref double value)
{
var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
return TsMasterApi.tsdb_get_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, ref value);
}
///
/// 获取信号值
///
///
///
///
///
///
[Browsable(false)]
public static int GetSignalValue(ref TLIBCANFD ACANFD, string AMsgName, string ASgnName, ref double value)
{
return TsMasterApi.tsdb_get_signal_value_canfd(ref ACANFD, AMsgName, ASgnName, ref value);
}
///
/// 设置信号值
///
///
///
///
///
///
///
///
///
public static int SetSignalValue(byte channel, string AMsgName, string ASgnName, double AValue, bool isSend = false, float sendPeriod = 0)
{
var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
find.ACANFD.FIdxChn = channel;
var re = TsMasterApi.tsdb_set_signal_value_canfd(ref find.ACANFD, AMsgName, ASgnName, AValue);
Debug.Assert(re == 0);
if (re != 0) throw new Exception($"设置报文失败!返回代码{re}");
if (re != 0) return re;
if (isSend)
{
if (sendPeriod == 0)
{
return TsMasterApi.tsapp_transmit_canfd_async(ref find.ACANFD);
}
else
{
return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
}
}
return 0;
}
///
/// 设置信号值
///
///
///
///
///
//public static int SetSignalValue(byte channel, string AMsgName, float sendPeriod = 0)
//{
// var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
// find.ACANFD.FIdxChn = channel;
// if (sendPeriod == 0)
// {
// return TsMasterApi.tsapp_transmit_canfd_async(ref find.ACANFD);
// }
// else
// {
// return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
// }
//}
///
/// 设置信号值
///
///
///
///
///
public static int SetSignalValue(APP_CHANNEL channel, string AMsgName, float sendPeriod = 0)
{
var find = DBCParse.MsgDatabase[(byte)channel].First(s => s.msg_name == AMsgName);
find.ACANFD.FIdxChn = (byte)channel;
if (sendPeriod == 0)
{
return TsMasterApi.tsapp_transmit_canfd_async(ref find.ACANFD);
}
else
{
return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
}
}
///
/// 发送自定义报文
///
///
[Browsable(false)]
public static int SetMsg(TLIBCANFD msg)
{
return TsMasterApi.tsapp_transmit_canfd_async(ref msg);
}
///
/// 设置报文
///
/// 通道
/// DBC数据库ID
/// 报文数组
public static void SetMsg(APP_CHANNEL channel, int ID, byte[] bytes)
{
var find = DBCParse.MsgDatabase[(byte)channel].FirstOrDefault(s => s.ACANFD.FIdentifier == ID);
if (find != null)
{
Array.Copy(bytes, 0, find.ACANFD.FData, 0, Math.Min(bytes.Length, find.ACANFD.FData.Length));
}
}
///
/// 发送自定义报文
///
///
///
///
///
///
///
///
///
///
///
///
///
public static int SendMsg(APP_CHANNEL AIdxChn, int AID, bool AIsTx, bool AIsExt,
bool AIsRemote, byte ADLC, byte[] ADataArray, bool AIsFD = true, bool AIsBRS = false,
bool isUpdateDBCDatabase = false, float sendPeriod = 0)
{
var send = new TLIBCANFD
{
FIdxChn = (byte)AIdxChn,
FProperties = 0,
FIdentifier = AID,
FDLC = ADLC,
FTimeUS = 0uL,
FData = new byte[64],
FFDProperties = 0,
FIsTx = AIsTx,
FIsError = false,
FIsExt = AIsExt,
FIsRemote = AIsRemote,
FIsFD = AIsFD,
FIsBRS = AIsBRS
};
int length = Math.Min(ADataArray.Length, 64);
Array.Copy(ADataArray, 0, send.FData, 0, length);
int re;
if (sendPeriod == 0)
{
re = TsMasterApi.tsapp_transmit_canfd_async(ref send);
}
else
{
re = TsMasterApi.tsapp_add_cyclic_msg_canfd(ref send, sendPeriod);
}
if (isUpdateDBCDatabase)
{
var find = DBCParse.MsgDatabase[(byte)AIdxChn].FirstOrDefault(s => s.ACANFD.FIdentifier == send.FIdentifier);
if (find != null)
{
Array.Copy(send.FData, 0, find.ACANFD.FData, 0, Math.Min(ADataArray.Length, find.ACANFD.FData.Length));
}
}
return re;
}
///
/// 添加循环发送报文
///
///
///
///
///
public static int AddCyclicMsg(byte channel, string AMsgName, float sendPeriod)
{
var find = DBCParse.MsgDatabase[channel].First(s => s.msg_name == AMsgName);
find.ACANFD.FIdxChn = channel;
return TsMasterApi.tsapp_add_cyclic_msg_canfd(ref find.ACANFD, sendPeriod);
}
///
/// 清除循环发送的报文
///
///
public static int DeleteCyclicMsgs()
{
return TsMasterApi.tsapp_delete_cyclic_msgs();
}
///
/// 获取错误提示
///
/// 错误代码
///
public static string GetErrorDescription(int errorCode)
{
IntPtr ADesc = IntPtr.Zero;
TsMasterApi.tsapp_get_error_description(errorCode, ref ADesc);
if (ADesc == IntPtr.Zero) return $"未知错误代码: {errorCode}";
// 假设返回的是 ANSI 字符串(如 C 的 char*)
string? description = Marshal.PtrToStringAnsi(ADesc);
return description ?? $"未知错误代码: {errorCode}";
}
#region CANFD转换相关方法
///
/// CANFD转CAN
/// 注意:如果CANFD报文长度超过8字节,转换时会截断数据。
///
/// CANFD消息
/// CAN消息
public static TLIBCAN CANFDToCAN(TLIBCANFD canfdMsg)
{
TLIBCAN canMsg = new TLIBCAN
{
FIdxChn = canfdMsg.FIdxChn,
FProperties = canfdMsg.FProperties,
FIdentifier = canfdMsg.FIdentifier,
FData = new byte[8], // CAN标准数据长度
FTimeUS = canfdMsg.FTimeUS, // 时间戳保持不变
FDLC = canfdMsg.FDLC > 8 ? (byte)8 : canfdMsg.FDLC, // DLC限制在8以内
FIsTx = canfdMsg.FIsTx,
FIsError = canfdMsg.FIsError,
FIsExt = canfdMsg.FIsExt,
FIsRemote = canfdMsg.FIsRemote
};
// 复制数据,只取前8字节
Array.Copy(canfdMsg.FData, 0, canMsg.FData, 0, Math.Min(8, canfdMsg.FData.Length));
return canMsg;
}
///
/// CAN转CANFD
///
/// CAN消息
/// CANFD消息
public static TLIBCANFD CANToCANFD(TLIBCAN canMsg)
{
TLIBCANFD canfdMsg = new TLIBCANFD
{
FIdxChn = canMsg.FIdxChn,
FProperties = canMsg.FProperties, // 保留原始属性
FIdentifier = canMsg.FIdentifier,
FData = new byte[64], // CANFD最大数据长度
FTimeUS = canMsg.FTimeUS,
FDLC = canMsg.FDLC,
FFDProperties = 0, // 新的CANFD报文,FD属性初始化为0
FIsTx = canMsg.FIsTx,
FIsError = canMsg.FIsError,
FIsExt = canMsg.FIsExt,
FIsRemote = canMsg.FIsRemote,
FIsFD = false, // 从CAN转换,明确设置为非FD
FIsBRS = false // 从CAN转换,明确设置为不支持BRS
};
// 复制数据
Array.Copy(canMsg.FData, 0, canfdMsg.FData, 0, Math.Min(64, canMsg.FData.Length));
return canfdMsg;
}
#endregion
#region CANFD报文属性获取方法
///
/// 获取CANFD报文内容
///
/// CANFD消息
/// 报文数据数组,长度为FDLC指定的长度
public static byte[] GetCANFDMsgContent(TLIBCANFD canfdMsg)
{
byte[] content = new byte[Math.Min(canfdMsg.FData.Length, canfdMsg.FDLC)];
Array.Copy(canfdMsg.FData, 0, content, 0, content.Length);
return content;
}
///
/// 获取CANFD报文时间戳 (微秒)
///
/// CANFD消息
/// 时间戳 (微秒)
public static ulong GetCANFDMsgTimestamp(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FTimeUS;
}
///
/// 获取CANFD报文数据长度 (DLC)
///
/// CANFD消息
/// 数据长度 (DLC)
public static byte GetCANFDMsgDataLength(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FDLC;
}
///
/// 获取CANFD报文是否为错误帧
///
/// CANFD消息
/// 是否为错误帧
public static bool GetCANFDMsgIsError(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FIsError;
}
///
/// 获取CANFD报文通道
///
/// CANFD消息
/// 通道号
public static byte GetCANFDMsgChannel(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FIdxChn;
}
///
/// 获取CANFD报文FD相关属性 (具体含义需参考TSMaster文档)
///
/// CANFD消息
/// FD属性
public static uint GetCANFDMsgFDProperties(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FFDProperties;
}
///
/// 获取CANFD报文基础属性 (具体含义需参考TSMaster文档)
///
/// CANFD消息
/// 基础属性
public static uint GetCANFDMsgProperties(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FProperties;
}
///
/// 获取CANFD报文标识符 (ID)
///
/// CANFD消息
/// 标识符 (ID)
public static uint GetCANFDMsgIdentifier(ref TLIBCANFD canfdMsg)
{
return (uint)canfdMsg.FIdentifier;
}
///
/// 获取CANFD报文是否为FD帧
///
/// CANFD消息
/// 是否为FD帧
public static bool GetCANFDMsgIsFD(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FIsFD;
}
///
/// 获取CANFD报文是否为远程帧
///
/// CANFD消息
/// 是否为远程帧
public static bool GetCANFDMsgIsRemote(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FIsRemote;
}
///
/// 获取CANFD报文是否为扩展帧
///
/// CANFD消息
/// 是否为扩展帧
public static bool GetCANFDMsgIsExt(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FIsExt;
}
///
/// 获取CANFD报文是否为BRS (Bit Rate Switch)
///
/// CANFD消息
/// 是否为BRS
public static bool GetCANFDMsgIsBRS(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FIsBRS;
}
///
/// 获取CANFD报文是否为发送帧
///
/// CANFD消息
/// 是否为发送帧
public static bool GetCANFDMsgIsTx(ref TLIBCANFD canfdMsg)
{
return canfdMsg.FIsTx;
}
///
/// 获取CANFD报文是否为ESI (Error State Indicator)
/// 注意:此API接口可能无法直接从TLIBCANFD结构获取ESI值。
/// ESI通常由总线决定,接收时反映发送节点的错误状态。
/// 当前实现返回FFDProperties的最低位,但这可能不准确。
/// 实际使用中可能需要通过其他方式或API获取。
///
/// CANFD消息
/// 是否为ESI (当前实现仅供参考)
public static bool GetCANFDMsgIsESI(ref TLIBCANFD canfdMsg)
{
// API文档未明确提供直接获取ESI的字段。
// 在CANFD协议中,ESI是报文中的一个位,由发送节点根据自身状态设置。
// TSMaster的TLIBCANFD结构体可能没有直接暴露这个原始位。
// FFDProperties可能包含相关信息,但具体哪一位是ESI需要查阅更详细的文档。
// 目前根据结构体字段推测,这可能不准确。
// 假设ESI信息可能隐含在FFDProperties中,但这种假设通常是错误的。
// 更可能的是,ESI信息在硬件层面处理,或通过其他方式反映。
// 因此,当前返回值可能不准确,需要根据实际API文档确认。
// 这里保留原实现,但加上说明。
return (canfdMsg.FFDProperties & 0x01) != 0; // 警告:此实现可能不正确
}
#endregion
#region CANFD报文设置方法
///
/// 设置CANFD报文内容
///
/// CANFD消息
/// 要设置的数据
/// 设置结果 (0为成功)
public static int SetCANFDMsgContent(ref TLIBCANFD canfdMsg, byte[] data)
{
if (data == null || data.Length == 0)
return -1; // 错误代码
int length = Math.Min(data.Length, canfdMsg.FData.Length);
Array.Copy(data, 0, canfdMsg.FData, 0, length);
canfdMsg.FDLC = (byte)length; // 同时更新DLC
return 0;
}
///
/// 设置CANFD报文时间戳 (微秒)
/// 注意:此时间戳通常由硬件/驱动在接收时设置,发送时设置可能无效或有特殊用途。
///
/// CANFD消息
/// 时间戳 (微秒)
/// 设置结果 (0为成功)
public static int SetCANFDMsgTimestamp(ref TLIBCANFD canfdMsg, ulong timestamp)
{
canfdMsg.FTimeUS = timestamp;
return 0;
}
///
/// 设置CANFD报文数据长度 (DLC)
///
/// CANFD消息
/// 数据长度 (DLC)
/// 设置结果 (0为成功)
public static int SetCANFDMsgDataLength(ref TLIBCANFD canfdMsg, byte length)
{
if (length > canfdMsg.FData.Length)
return -1; // 错误代码,长度超出数组大小
canfdMsg.FDLC = length;
return 0;
}
///
/// 设置CANFD报文是否为错误帧
///
/// CANFD消息
/// 是否为错误帧
/// 设置结果 (0为成功)
public static int SetCANFDMsgIsError(ref TLIBCANFD canfdMsg, bool isError)
{
canfdMsg.FIsError = isError;
return 0;
}
///
/// 设置CANFD报文通道
///
/// CANFD消息
/// 通道号
/// 设置结果 (0为成功)
public static int SetCANFDMsgChannel(ref TLIBCANFD canfdMsg, byte channel)
{
canfdMsg.FIdxChn = channel;
return 0;
}
///
/// 设置CANFD报文FD相关属性
///
/// CANFD消息
/// FD属性
/// 设置结果 (0为成功)
public static int SetCANFDMsgFDProperties(ref TLIBCANFD canfdMsg, uint fdProperties)
{
canfdMsg.FFDProperties = (byte)fdProperties;
return 0;
}
///
/// 设置CANFD报文基础属性
///
/// CANFD消息
/// 基础属性
/// 设置结果 (0为成功)
public static int SetCANFDMsgProperties(ref TLIBCANFD canfdMsg, uint properties)
{
canfdMsg.FProperties = (byte)properties;
return 0;
}
///
/// 设置CANFD报文标识符 (ID)
///
/// CANFD消息
/// 标识符 (ID)
/// 设置结果 (0为成功)
public static int SetCANFDMsgIdentifier(ref TLIBCANFD canfdMsg, uint identifier)
{
canfdMsg.FIdentifier = (int)identifier;
return 0;
}
///
/// 设置CANFD报文是否为FD帧
///
/// CANFD消息
/// 是否为FD帧
/// 设置结果 (0为成功)
public static int SetCANFDMsgIsFD(ref TLIBCANFD canfdMsg, bool isFD)
{
canfdMsg.FIsFD = isFD;
return 0;
}
///
/// 设置CANFD报文是否为远程帧
///
/// CANFD消息
/// 是否为远程帧
/// 设置结果 (0为成功)
public static int SetCANFDMsgIsRemote(ref TLIBCANFD canfdMsg, bool isRemote)
{
canfdMsg.FIsRemote = isRemote;
return 0;
}
///
/// 设置CANFD报文是否为扩展帧
///
/// CANFD消息
/// 是否为扩展帧
/// 设置结果 (0为成功)
public static int SetCANFDMsgIsExt(ref TLIBCANFD canfdMsg, bool isExt)
{
canfdMsg.FIsExt = isExt;
return 0;
}
///
/// 设置CANFD报文是否为BRS (Bit Rate Switch)
///
/// CANFD消息
/// 是否为BRS
/// 设置结果 (0为成功)
public static int SetCANFDMsgIsBRS(ref TLIBCANFD canfdMsg, bool isBRS)
{
canfdMsg.FIsBRS = isBRS;
return 0;
}
///
/// 设置CANFD报文是否为发送帧
///
/// CANFD消息
/// 是否为发送帧
/// 设置结果 (0为成功)
public static int SetCANFDMsgIsTx(ref TLIBCANFD canfdMsg, bool isTx)
{
canfdMsg.FIsTx = isTx;
return 0;
}
///
/// 设置CANFD报文是否为ESI (Error State Indicator)
/// 注意:此API接口可能无法直接设置TLIBCANFD结构中的ESI值。
/// ESI通常由硬件根据发送节点的错误状态自动设置。
/// 当前实现通过操作FFDProperties的最低位来模拟,但这可能无效或不正确。
/// 实际使用中可能无法或不应通过这种方式设置。
///
/// CANFD消息
/// 是否为ESI (当前实现仅供参考,可能无效)
/// 设置结果 (0为成功)
public static int SetCANFDMsgIsESI(ref TLIBCANFD canfdMsg, bool isESI)
{
// 使用 byte 类型的掩码进行位操作
byte mask = 0x01; // 最低位
if (isESI)
canfdMsg.FFDProperties |= mask; // 设置最低位
else
canfdMsg.FFDProperties &= (byte)~mask; // 清除最低位 (注意:~mask 会得到 -2,所以需要强制转换为 byte)
return 0;
}
#endregion
///
/// 获取CANFD报文指定字节的指定位的值 (0 或 1)
///
/// CANFD消息
/// 字节索引 (0-63 for CANFD)
/// 位索引 (0-7)
/// 位的值 (0 或 1),如果索引无效则返回 -1
public static int GetCANFDMsgBitValue(ref TLIBCANFD canfdMsg, int byteIndex, int bitIndex)
{
if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length || bitIndex < 0 || bitIndex > 7)
{
Debug.WriteLine($"GetCANFDMsgBitValue: Invalid index - byteIndex: {byteIndex}, bitIndex: {bitIndex}");
return -1; // 或者抛出异常
}
byte mask = (byte)(1 << bitIndex);
return (canfdMsg.FData[byteIndex] & mask) != 0 ? 1 : 0;
}
///
/// 设置CANFD报文指定字节的指定位的值
///
/// CANFD消息
/// 字节索引 (0-63 for CANFD)
/// 位索引 (0-7)
/// 要设置的值 (0 或 1)
/// 操作结果 (0为成功, -1为失败)
public static int SetCANFDMsgBitValue(ref TLIBCANFD canfdMsg, int byteIndex, int bitIndex, int value)
{
if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length || bitIndex < 0 || bitIndex > 7 || (value != 0 && value != 1))
{
Debug.WriteLine($"SetCANFDMsgBitValue: Invalid input - byteIndex: {byteIndex}, bitIndex: {bitIndex}, value: {value}");
return -1; // 或者抛出异常
}
byte mask = (byte)(1 << bitIndex);
if (value == 1)
{
canfdMsg.FData[byteIndex] |= mask; // 设置该位
}
else
{
canfdMsg.FData[byteIndex] &= (byte)~mask; // 清除该位
}
return 0;
}
///
/// 对CANFD报文指定字节执行按位与(&)操作
///
/// CANFD消息
/// 字节索引 (0-63 for CANFD)
/// 要与的掩码值 (byte)
/// 操作结果 (0为成功, -1为失败)
public static int BitwiseAndCANFDMsgByte(ref TLIBCANFD canfdMsg, int byteIndex, byte mask)
{
if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length)
{
Debug.WriteLine($"BitwiseAndCANFDMsgByte: Invalid byteIndex - {byteIndex}");
return -1;
}
canfdMsg.FData[byteIndex] &= mask;
return 0;
}
///
/// 对CANFD报文指定字节执行按位或(|)操作
///
/// CANFD消息
/// 字节索引 (0-63 for CANFD)
/// 要或的掩码值 (byte)
/// 操作结果 (0为成功, -1为失败)
public static int BitwiseOrCANFDMsgByte(ref TLIBCANFD canfdMsg, int byteIndex, byte mask)
{
if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length)
{
Debug.WriteLine($"BitwiseOrCANFDMsgByte: Invalid byteIndex - {byteIndex}");
return -1;
}
canfdMsg.FData[byteIndex] |= mask;
return 0;
}
///
/// 对CANFD报文指定字节执行按位异或(^)操作
///
/// CANFD消息
/// 字节索引 (0-63 for CANFD)
/// 要异或的掩码值 (byte)
/// 操作结果 (0为成功, -1为失败)
public static int BitwiseXorCANFDMsgByte(ref TLIBCANFD canfdMsg, int byteIndex, byte mask)
{
if (byteIndex < 0 || byteIndex >= canfdMsg.FData.Length)
{
Debug.WriteLine($"BitwiseXorCANFDMsgByte: Invalid byteIndex - {byteIndex}");
return -1;
}
canfdMsg.FData[byteIndex] ^= mask;
return 0;
}
#region CAN Message Handling (为CAN添加位操作方法)
///
/// 获取CAN报文指定字节的指定位的值 (0 或 1)
///
/// CAN消息
/// 字节索引 (0-7 for CAN)
/// 位索引 (0-7)
/// 位的值 (0 或 1),如果索引无效则返回 -1
public static int GetCANMsgBitValue(ref TLIBCAN canMsg, int byteIndex, int bitIndex)
{
if (byteIndex < 0 || byteIndex >= canMsg.FData.Length || bitIndex < 0 || bitIndex > 7)
{
Debug.WriteLine($"GetCANMsgBitValue: Invalid index - byteIndex: {byteIndex}, bitIndex: {bitIndex}");
return -1;
}
byte mask = (byte)(1 << bitIndex);
return (canMsg.FData[byteIndex] & mask) != 0 ? 1 : 0;
}
///
/// 设置CAN报文指定字节的指定位的值
///
/// CAN消息
/// 字节索引 (0-7 for CAN)
/// 位索引 (0-7)
/// 要设置的值 (0 或 1)
/// 操作结果 (0为成功, -1为失败)
public static int SetCANMsgBitValue(ref TLIBCAN canMsg, int byteIndex, int bitIndex, int value)
{
if (byteIndex < 0 || byteIndex >= canMsg.FData.Length || bitIndex < 0 || bitIndex > 7 || (value != 0 && value != 1))
{
Debug.WriteLine($"SetCANMsgBitValue: Invalid input - byteIndex: {byteIndex}, bitIndex: {bitIndex}, value: {value}");
return -1;
}
byte mask = (byte)(1 << bitIndex);
if (value == 1)
{
canMsg.FData[byteIndex] |= mask;
}
else
{
canMsg.FData[byteIndex] &= (byte)~mask;
}
return 0;
}
///
/// 对CAN报文指定字节执行按位与(&)操作
///
/// CAN消息
/// 字节索引 (0-7 for CAN)
/// 要与的掩码值 (byte)
/// 操作结果 (0为成功, -1为失败)
public static int BitwiseAndCANMsgByte(ref TLIBCAN canMsg, int byteIndex, byte mask)
{
if (byteIndex < 0 || byteIndex >= canMsg.FData.Length)
{
Debug.WriteLine($"BitwiseAndCANMsgByte: Invalid byteIndex - {byteIndex}");
return -1;
}
canMsg.FData[byteIndex] &= mask;
return 0;
}
///
/// 对CAN报文指定字节执行按位或(|)操作
///
/// CAN消息
/// 字节索引 (0-7 for CAN)
/// 要或的掩码值 (byte)
/// 操作结果 (0为成功, -1为失败)
public static int BitwiseOrCANMsgByte(ref TLIBCAN canMsg, int byteIndex, byte mask)
{
if (byteIndex < 0 || byteIndex >= canMsg.FData.Length)
{
Debug.WriteLine($"BitwiseOrCANMsgByte: Invalid byteIndex - {byteIndex}");
return -1;
}
canMsg.FData[byteIndex] |= mask;
return 0;
}
///
/// 对CAN报文指定字节执行按位异或(^)操作
///
/// CAN消息
/// 字节索引 (0-7 for CAN)
/// 要异或的掩码值 (byte)
/// 操作结果 (0为成功, -1为失败)
public static int BitwiseXorCANMsgByte(ref TLIBCAN canMsg, int byteIndex, byte mask)
{
if (byteIndex < 0 || byteIndex >= canMsg.FData.Length)
{
Debug.WriteLine($"BitwiseXorCANMsgByte: Invalid byteIndex - {byteIndex}");
return -1;
}
canMsg.FData[byteIndex] ^= mask;
return 0;
}
#endregion
}
}