现场优化4

This commit is contained in:
2026-08-15 18:43:38 +08:00
parent 8d941d92f0
commit 92eab2f626
5 changed files with 249 additions and 31 deletions
+72 -4
View File
@@ -688,6 +688,7 @@ namespace ZLGUSBCANFD
/// <summary>
/// 发送自定义报文(原始字节,帧 ID 支持 string 兼容模式)。
/// 循环发送间隔毫秒 = 0 时只发送一次;>0 时按指定间隔循环发送,可调用 停止循环发送 停止。
/// </summary>
/// <param name="通道号">CAN/CANFD 通道索引</param>
/// <param name="帧IDStr">帧 ID(可以是 "26"、"0x1A"、"1A");扩展帧会自动置位 0x80000000</param>
@@ -696,6 +697,7 @@ namespace ZLGUSBCANFD
/// <param name="是否是扩展帧">是否为 29 位扩展帧</param>
/// <param name="是否是CANFD">true = CANFDfalse = 经典 CAN</param>
/// <param name="开启波特率加速BRS">CANFD 是否开启波特率加速</param>
/// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(毫秒)</param>
public virtual bool (
uint ,
string IDStr,
@@ -703,7 +705,8 @@ namespace ZLGUSBCANFD
byte dlcLength,
bool = false,
bool CANFD = true,
bool BRS = true)
bool BRS = true,
int = 0)
{
if (!TryParseFrameId(IDStr, out uint ID))
{
@@ -713,23 +716,88 @@ namespace ZLGUSBCANFD
if ( >= _maxChannels || _channelHandles[] == IntPtr.Zero) return false;
if ( == null) return false;
if ( < 0) throw new ArgumentOutOfRangeException(nameof(), "循环发送间隔必须大于或等于 0。");
// 扩展帧需要把最高位标志位置起来
uint canId = ID & 0x7FFFFFFF;
if () canId |= 0x80000000;
// 单次发送
if ( == 0)
{
return (, canId, , dlcLength, , CANFD, BRS);
}
// 循环发送:先停止同通道同帧 ID 的旧循环,再启动新循环
(, ID);
// 拷贝原始数据,避免外部修改影响循环发送
byte[] dataCopy = new byte[.Length];
Array.Copy(, dataCopy, .Length);
var cts = new CancellationTokenSource();
var sendTask = Task.Run(async () =>
{
while (!cts.Token.IsCancellationRequested)
{
if (_isClosing) break;
try
{
lock (_channelLocks[])
{
if (_channelHandles[] == IntPtr.Zero || _isClosing) break;
(, canId, dataCopy, dlcLength, , CANFD, BRS);
}
await Task.Delay(, cts.Token);
}
catch (OperationCanceledException)
{
break;
}
catch (Exception ex)
{
Logger.LoggerHelper.Error($"[ZLGCANFD] 循环发送自定义报文失败: {ex.Message}");
break;
}
}
if (_cyclicSenders.TryGetValue((, ID), out var current) && ReferenceEquals(current.Cts, cts))
{
_cyclicSenders.TryRemove((, ID), out _);
}
cts.Dispose();
}, cts.Token);
_cyclicSenders[(, ID)] = (cts, sendTask);
return true;
}
/// <summary>
/// 发送自定义报文的单次执行(内部方法,无循环逻辑)。
/// </summary>
[Browsable(false)]
private bool (
uint ,
uint canId,
byte[] ,
byte dlcLength,
bool ,
bool CANFD,
bool BRS)
{
lock (_channelLocks[])
{
if (CANFD)
{
// CANFD 有效 DLC 校验
byte validFdDlc = CANFD的Dlc(dlcLength);
ZLGCAN.canfd_frame fdFrame = new ZLGCAN.canfd_frame
{
can_id = canId,
len = validFdDlc,
flags = (byte)(( ? 0x01 : 0x00) | (BRS ? 0x02 : 0x00) | 0x20), // 0x20 本地回显
flags = (byte)(( ? 0x01 : 0x00) | (BRS ? 0x02 : 0x00) | 0x20),
data = new byte[64]
};
Array.Copy(, 0, fdFrame.data, 0, Math.Min(.Length, 64));
@@ -749,7 +817,7 @@ namespace ZLGUSBCANFD
{
can_id = canId,
can_dlc = dlcLength > 8 ? (byte)8 : dlcLength,
__pad = 0x20, // 发送回显
__pad = 0x20,
data = new byte[8]
};
Array.Copy(, 0, standardFrame.data, 0, Math.Min(.Length, 8));