c# - .NET SerialPort Write() 添加字符和移动字节

标签 c# serial-port embedded

我正在使用 VisualStudio 2015 在 C# 中开发固件升级应用程序。该应用程序使用基于 XAML 的表单和 C# 代码。固件升级的目标是运行 STM32F417 处理器(ARM Cortex M4)的定制板。 C# 代码与 417 连接,使 417 跳转到其引导加载程序(出厂安装)并使用引导加载程序 API 加载新固件。

每次传输 256 字节(允许的最大传输量)后,将发送数据的校验和和字节数,并从 417 接收到 ACK 字节以表明该传输的所有内容均已检查。传输将在几个 256 block 之后失败,为了测试传输,我将 C# 代码设置为只传输 .hex 文件,而不进行任何其他检查。

我设置代码以将更新的固件作为 .hex 文件传输。逐行。它通过串行线写出数据,并在 super 终端中以文本形式捕获。 我将其实现为 256 字节的写入:

        byte[] buffer256 = new byte[256];

        // Read the file and process one line at a time
        System.IO.StreamReader file = new System.IO.StreamReader(path);
        while ((line = file.ReadLine()) != null)
        {
            line = line.Substring(1, line.Length - 1);

            // Create byte array from string
            var bytes = GetBytesFromByteString(line).ToArray();

            // Assign values to variables from byte array
            type = bytes[3];

            // BLOCK WRITE TO MEMORY
            if (type == 0) // data type
            {
                length = bytes[0];

                if (byteCounter >= 255)
                {
                    _serialPort.Write(buffer256, 0, 256);

                    Array.Clear(buffer256, 0, buffer256.Length);
                    byteCounter = 0;
                }

                for (int i = 0; i < length; i++)
                {
                    buffer256[byteCounter++] = bytes[4 + i];
                }
            }  // end BLOCK WRITE TO MEMORY

             counter++;
        } // end WHILE loop for loading hex file

        file.Close();

也作为单个字节的写入:

        byte[] buffer256 = new byte[256];

        // Read the file and process one line at a time
        System.IO.StreamReader file = new System.IO.StreamReader(path);
        while ((line = file.ReadLine()) != null)
        {
            line = line.Substring(1, line.Length - 1);

            // Create byte array from string
            var bytes = GetBytesFromByteString(line).ToArray();

            // Assign values to variables from byte array
            type = bytes[3];

            if (type == 0)
            {
                length = bytes[0];

                for (int i = 0; i < length; i++)
                {
                    _serialPort.Write(bytes, 4 + i, 1);

                } // end FOR loop

            }// end SINGLE BYTE WRITING

             counter++;
        } // end WHILE loop for loading hex file

        file.Close();

在这两种情况下,十六进制文件都是通过使用 SerialPort 类写入来更改的。我尝试了各种其他方法,甚至在构建 SerialPort 类的 BaseStream 类中尝试了 WriteAsync(覆盖 Stream 方法)。

这是原始 .hex 文件(仅数据)与接收到的数据相比的样本(8 个字):

Original:
00F8012B 002AF9D1 18467047 70B50646
2DF0FEFC 04680546 0A220021 304600F0

Received:
00F8012B 002AF9D1 18464670 4770B506
462DF0FE FC046805 460A2200 21304600

这些是 13391 中的第 49 行和第 50 行。一些 block 的校验和也经过检查并且是错误的。我很确定这就是固件升级失败的原因——引导加载程序正在根据接收到的内容计算校验和,但在将其与 C# 应用程序正在计算和发送的校验和进行比较时失败。

我的问题是:如果 SerialPort(和底层 Stream)不可靠,我应该用什么替换它以及如何替换它?是否可以只替换 SerialPort 类,也许用 C++ 类?或者用 C++ 或其他语言重写整个应用程序会更好吗?

最佳答案

SerialPort 类本身并不是不可靠的。我已经在台式机和许多 CE 设备上成功地使用了它。问题可能出在任一端的硬件、其中一个操作系统、一些繁琐的配置值或任何这些的某种组合。

它也可能是您的代码。我不确定你做错了什么,但使用 ReadLine 将二进制数据读入字符串对我来说似乎很奇怪。您是否已在调试器中验证 bytes[] 是否正确?

PS——如果其中一个硬件问题与时序有关,切换到 C++ 可能会有帮助。 Interop 对于这样的事情来说非常轻松,所以我不会费心重写整个应用程序,但我不知道你的情况所以不能肯定地说。

关于c# - .NET SerialPort Write() 添加字符和移动字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45644239/

相关文章:

c# - C++/CLI 中是否存在 C# 的不安全等效项?

c# - Bing Maps 如何检查一个点是否在 map 范围内?

c# - POS协议(protocol)串口通讯

c# - 如何调试 dotnet ef 数据库删除?

c# - HttpWebRequest、重定向、实时站点上的分块编码错误,但在本地 IIS Express 中有效

linux - 如何调整 inotify 以使用更少的内存?

c++ - 使用 malloc 和 void 指针复制临时结构

c - 如何在微 Controller 硬件复位之前保存一些数据?

java - 是否有支持 Telnet RFC2217(通过网络连接与 COM 端口通信)的 Java 客户端?

linux - 如何在 Linux 中创建一个将数据代理到真实设备的虚拟 io 设备?