1 Star 0 Fork 0

yangming886/SerialPortStream

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MS-PL

SerialPortStream is an independent implementation of System.IO.Ports.SerialPort and SerialStream for better reliability and maintainability.

The SerialPortStream is a ground up implementation of a Stream that buffers data to and from a serial port. It uses low level Win32API for managing events and asynchronous I/O, using a programming model as in the MSDN PipeServer example.

Why another Serial Port implementation?

Microsoft already provides a reasonable implementation for accessing the serial port. Unfortunately, documentation is sparse. When one tries to find information about how to program the serial port one comes across instead many blogs and forums describing the issues that they've observed.

Through the implementation of SerialPortStream, I've used ILSpy to reverse engineer how the Microsoft implementation works, discovering many other subtle, but noteworthy implementation issues.

System Requirements

Tested

Software has been developed using:

  • .NET 4.0 and 4.5 on Windows 7 x86 and x64.
  • .NET 4.5 on Windows 8 Pro x64 and Windows 8.1 Pro x64.

I use this software for automation in another system that runs for multiple days and it appears stable.

Not Compatible

SerialPortStream is not designed for the Compact Framework. Nor will it work in the Mono framework due to the heavy dependencies on the Win32 API.

Untested, but should work:

Theoretically it should work on the following, but it hasn't been tested.

  • It should work on Windows XP with .NET 4.0

Installation

You can download the release for 1.2.0, which contains binaries compiled against Framework version 4.0 and 4.5. You can also install the NuGet package at http://www.nuget.org/packages/SerialPortStream/

Goals

This project tries to achieve the following:

  • An implementation similar to the MS implementation of SerialPort. It's not meant to be 100% compatible, but instead provide similar functionality
  • Abstract the driver implementation and provide for a more reliable transport, by making writing serial data completely buffered. With the MS implementation, one can write data, but subsequently needs to check if all data is written or not. If it isn't written, then it needs to be retried. The SerialPortStream makes this easier.
  • Provide for reliable and consistent behaviour. See the next section.

Issues with MS Serial Port

The SerialPortStream tries to solve the following issues observed:

  • Zach Saw describes issues regarding behaviour of the fAbortError flag in the Serial DCB. The SerialPortStream defines this flag.
  • Closing a serial port, then reopening it generally causes problems. The SerialPortStream shouldn't have this issue.
  • The ReadTo() implementation can subtly change the byte stream buffer, when one switches from characters to bytes. This problem occurs because the MS implementation actually converts the characters back to bytes into its buffer. So if you have UTF8, decoded some invalid characters and then have a timeout, this results in the invalid characters being converted back to bytes, resulting in "lost" data. I take some care when decoding bytes to characters to ensure a seamless and accurate transition between bytes and characters.
  • Write() gives the data to the serial port. If the operation is asynchronous, the callback results in the number of bytes that were actually transferred to the driver. You need to check yourself if this is valid or not. In the synchronous case, the data is simply thrown away. The SerialPortStream method simply copies data to a local buffer and uses asynchronous writes in a different thread. It works hard in the background to send out the data you provided. If the data can't be sent, then you get a TimeoutException without any data being buffered at all. So you can implement reliable protocols and your code is simpler.

Extra Features

  • You can obtain the RingIndicator pin status.
  • The Read() and Write() buffers are completely independent of the low level Windows driver.

Reading and Writing - Buffering

Why is it interesting to perform buffering? A driver might be configured to be 4096 or 8192 bytes (which is quite typical). Testing with the PL2303 chipset, one can't write more than about 12KB with a single write operation.

A Write buffer may be 128KB, which one writes to. The thread in the background will write the data and issue as many write calls as is necessary to get the job done. A Read buffer may be 5MB. The background thread will read from the serial port when ever data arrives and buffers into the 5MB.

So long as the I/O thread in .NET an execute every 100-200ms, it can continue to read data from the driver. Your own application doesn't need to keep to such difficult time constraints. Such issues typically arise in Automation type environments where a computer has many different peripherals. So long as the process doesn't block, your main application might sleep for 10 seconds and you've still lost no data. The MS implementation wouldn't be so simple, you have to make sure that you perform frequent read operations else the driver itself might overflow (resulting in lost data).

Microsoft Public License (Ms-PL) This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution. 2. Grant of Rights (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.

简介

暂无描述 展开 收起
MS-PL
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/yangming886/SerialPortStream.git
git@gitee.com:yangming886/SerialPortStream.git
yangming886
SerialPortStream
SerialPortStream
v1.x

搜索帮助