You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET串口固件更新工具中显示传输速率与进度百分比?

PacketReceived事件未触发的原因

你当前处于Xmodem发送方角色,执行的是Send()发送固件的操作。PacketReceived事件仅在接收模式下(即调用Receive()方法接收数据时),收到对端发来的数据包才会触发,发送场景下该事件不会被激活,属于正常表现。

实时进度、传输速率实现方案

你已经找到的PacketToSend事件刚好可以用来统计发送进度,该事件会在每个数据包准备发送前触发,你可以通过累加每个包的大小计算已发送总字节数,结合总文件大小和传输耗时计算进度和速率,具体修改代码如下:

else
{
    var xmodem = new XModemCommunicator();
    mySerialPort.Close();
    var port = new SerialPort
    {
        BaudRate = 115200,
        DataBits = 8,
        Parity = Parity.None,
        StopBits = StopBits.One,
        Handshake = Handshake.None,
        PortName = com,
        RtsEnable = true,
        DtrEnable = true,
        NewLine = "\r",
    };
    xmodem.Port = port;
    xmodem.Data = File.ReadAllBytes(FileName);
    // 新增统计相关变量
    long totalBytes = xmodem.Data.Length;
    long sentBytes = 0;
    DateTime startTime = DateTime.Now;

    xmodem.Completed += (s, e) =>
    {
        // 传输完成覆盖进度行
        Console.SetCursorPosition(0, Console.CursorTop);
        Console.WriteLine($"进度:100% | 传输完成,共发送{Math.Round(totalBytes/1024.0,2)}KB数据");
        port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler2);
        port.Write("\r");
    };
    xmodem.Aborted += (s, e) =>
    {
        Console.SetCursorPosition(0, Console.CursorTop);
        Console.WriteLine("传输已终止\nPress enter to exit.");
    };

    xmodem.StateUpdated += (s, e) =>
    {
        Console.WriteLine(xmodem.State);
    };

    // 新增PacketToSend事件绑定,实现进度速率刷新
    xmodem.PacketToSend += (s, e) =>
    {
        sentBytes += e.PacketToSend.Count;
        double progress = Math.Round((double)sentBytes / totalBytes * 100, 1);
        double usedSeconds = (DateTime.Now - startTime).TotalSeconds;
        double speed = Math.Round(sentBytes / 1024 / usedSeconds, 2);
        // 清空当前行刷新显示,避免多行输出
        Console.SetCursorPosition(0, Console.CursorTop);
        Console.Write(new string(' ', Console.WindowWidth));
        Console.SetCursorPosition(0, Console.CursorTop);
        Console.Write($"进度:{progress}% | 传输速率:{speed}KB/s");
    };

    port.Open();
    // 发送数据
    xmodem.Send();
    
    if (xmodem.State != XModemStates.Idle)
    {
        xmodem.CancelOperation();
        Console.ReadLine();
    }
    Thread.Sleep(10000);
    port.Close();
    if (!port.IsOpen)
    {
        mySerialPort.Open();
    }
}

注意事项

  • 如果遇到Xmodem重发场景,同一个包可能多次触发PacketToSend事件,若需要更精准的统计,可以额外监听串口的ACK响应后再累加已发送字节,普通固件升级场景下重发概率极低,上述实现足够使用。
  • 若不需要进度显示占满整行,可以调整Console.SetCursorPosition的坐标参数适配你原有控制台的输出布局。

内容的提问来源于stack exchange,提问作者Jacky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:36:01