适用于多个平台的 Mono 串行端口 (rs232)

发布于 2024-07-11 19:41:29 字数 783 浏览 8 评论 0原文

我计划在 .NET 中重写 Win32 应用程序(本机 C++) - 最有可能使用 mono,这样我就可以在 Win32、Linux 和 Mac 上运行它。 我试图解决的问题(只真正为 Win32 开发)是串行端口定义的问题。 当只应该有一个可执行文件时,人们通常如何识别平台的差异。 具体来说,COM 端口在 Windows 中被标识为 COM1 或类似的名称 (\.\COM),但在 Linux 上它们被指定为类似 /dev/ttyS0 的名称。

人们是否会在运行时检查平台以获取此信息?

我认为唯一的区别是港口的开放和关闭。 阅读和写作是一样的。

也许这是一个更通用的问题,因为它适用于 mono/.NET 中任何特定于平台的内容。

你如何处理这个问题? 在某些字符串资源或配置文件中,或者基于运行时平台进行硬编码和切换?

有这方面的代码示例吗? 请注意,我是一名 C++ 开发人员,并不熟悉 .NET 中提供的所有类。 有没有办法从 CLR 获取串行端口命名方案,或者有没有办法从 CLR 获取操作系统/平台?

如果 CLR 能够以更独立的方式呈现串行端口,那就太好了。 也许那是不可能的。

谢谢, 蒂姆

编辑

鉴于到目前为止的一个回应,我想我应该尝试一下
首先枚举 SerialPort.GetPortNames() 看看是否有效。 (在两个平台上)

在 win32 中,对于更高的端口号和 USB 加密狗 - 它不像基本的 COM 端口枚举那么简单。

我将在这里报告调查结果。

I am planning on re-writing a Win32 application (native C++) in .NET - most likely using mono so I can run it on Win32, Linux and mac. The problem I am trying to solve (having only really developed for Win32) is an issue with the serial port definition. How does one typically identify differences in platform when there is only supposed to be one executable. Specifically, the COM port is identified in windows as COM1 or something like that (\.\COM) but on linux they are specified as something like /dev/ttyS0.

Does one check the platform at runtime for this information?

I think the only difference would be in the opening and closing of the port. The reading and writing is the same.

Perhaps this is a more generic question in that it applies to any platform-specific stuff in mono/.NET.

How do you handle this? In some string resource or config file, or hard-coded and switch based on runtime platform?

Any code sample for this? Note am a C++ developer and not familiar with all the classes available in .NET. is there a way to get either the serial port naming scheme from the CLR or is there a way to get the OS/Platform from the CLR?

it would have been nice for the CLR to have been able to present the serial ports in a more independent manner. Maybe that is not possible.

Thanks,
Tim

EDIT

Given the one response so far I guess I should just try the
SerialPort.GetPortNames() enumeration first to see if it works. (on both platforms)

In win32 for the higher port numbers and ofr the USB dongle - it is not as simple as the basic COM port enumeration.

I will report the findings here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苍风燃霜 2024-07-18 19:41:29

在.Net中,您需要System.IO.Ports。 “COM1”和“/dev/ttyS0”等名称是随机操作系统名称。 为什么需要对它们进行硬编码? 用户只需从可用端口列表中选择一个即可。

显然,您在运行时确定该列表。 事实上,对于 USB 转串口适配器,您可能需要考虑这样一种可能性:用户只有在启动程序后才发现他忘记连接 USB 转串口适配器。 这意味着您应该在每次显示配置对话框时重新阅读此列表。 顺便说一句,USB 适配器很可能不是 COM1。

(我不能保证 SerialPort 的 Mono 实现的质量。快速的谷歌搜索让我有点担心,但你自己测试一下)

In .Net, you need System.IO.Ports. Names like "COM1" and "/dev/ttyS0" are random OS names. Why do you need to hardcode them? The user should just pick one from the list of available ports.

Obviously, you determine this list at runtime. In fact, with USB-to-serial adaptors you might want to consider the possibility that the user discovers only after starting your program that he forgot to connect his USB-to-serial adaptor. That means you should reread this list every time you show the config dialog. The USB adaptor is quite likely not COM1, BTW.

(I can't vouch for the quality of the Mono implementation of SerialPort. A quick google search left me a bit worried, but test yourself)

一张白纸 2024-07-18 19:41:29

我看了一下,似乎用于枚举串行端口的单声道代码只能在 Linux 上工作。

(来自 mcs/class/System/System.IO.Ports/SerialPort.cs)

            public static string [] GetPortNames ()
            {
                    int p = (int) Environment.OSVersion.Platform;
                    List<string> serial_ports = new List<string>();

                    // Are we on Unix?
                    if (p == 4 || p == 128 || p == 6) {
                            string[] ttys = Directory.GetFiles("/dev/", "tty*");
                            foreach (string dev in ttys) {
                                    if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB"))
                                            serial_ports.Add(dev);
                            }
                    } else {

在 OSX 上,我认为您可能可以匹配 /dev/tty.* (FreeBSD 需要 /dev/ttyU[0-9]+)

我可以并不是说我很喜欢它选择运行哪个操作系统的方式。

I had a look at this and it seems the mono code for enumerating serial ports is not going to work on anything but Linux.

(from mcs/class/System/System.IO.Ports/SerialPort.cs)

            public static string [] GetPortNames ()
            {
                    int p = (int) Environment.OSVersion.Platform;
                    List<string> serial_ports = new List<string>();

                    // Are we on Unix?
                    if (p == 4 || p == 128 || p == 6) {
                            string[] ttys = Directory.GetFiles("/dev/", "tty*");
                            foreach (string dev in ttys) {
                                    if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB"))
                                            serial_ports.Add(dev);
                            }
                    } else {

On OSX I would think you could probably match /dev/tty.* (FreeBSD would need /dev/ttyU[0-9]+)

I can't say I'm enamoured of the way it picks which OS it's running under either..

孤蝉 2024-07-18 19:41:29

刚刚发现这个线程,我想我应该添加我的发现:随机地,我也担心 Mac 上的这个问题。 在 Windows 和 Linux 中(在 VS 和 Mono 中) SerialPort.GetPortNames() 返回一个列表,具有以下规则:

1) Windows 返回一个字符串列表,如 Com1、Com4,遗漏任何不存在的字符串(USB 串行适配器)似乎根据它们插入的插头获取 COM 号,一致)从我的串行端口扫描仪:

正在扫描 COM1
扫描COM4
扫描完成

2) Linux 返回 Linux 发行版的编译器已启用的所有可能的 tty 串行端口。 这似乎大约有 8 个端口,如果您尝试打开,将会抛出异常(来自我的串行端口扫描仪:

Scanning /dev/ttyS0
扫描 /dev/ttyS1 端口失败System.IO.IOException:I/O 错误
在System.IO.Ports.SerialPortStream..ctor(System.String portName,Int32 baudRate,Int32 dataBits,奇偶校验,StopBits stopBits,布尔dtrEnable,布尔rtsEnable,握手握手,Int32 readTimeout,Int32 writeTimeout,Int32 readBufferSize,Int32 writeBufferSize) [0x00000]
at(包装器远程调用带检查)System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System. IO.端口.握手,int,int,int,int)
在 System.IO.Ports.SerialPort.Open () [0x00000]
at (包装器远程调用带检查) System.IO.Ports.SerialPort:Open ()
在 HSMScanner.Program.Main (System.String[] args) [0x00000]
扫描 /dev/ttyS2 端口失败System.IO.IOException:I/O 错误
在System.IO.Ports.SerialPortStream..ctor(System.String portName,Int32 baudRate,Int32 dataBits,奇偶校验,StopBits stopBits,布尔dtrEnable,布尔rtsEnable,握手握手,Int32 readTimeout,Int32 writeTimeout,Int32 readBufferSize,Int32 writeBufferSize) [0x00000]
at(包装器远程调用带检查)System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System. IO.端口.握手,int,int,int,int)
在 System.IO.Ports.SerialPort.Open () [0x00000]
at (包装器远程调用带检查) System.IO.Ports.SerialPort:Open ()
在 HSMScanner.Program.Main (System.String[] args) [0x00000]
扫描 /dev/ttyS3 端口失败System.IO.IOException:I/O 错误
在System.IO.Ports.SerialPortStream..ctor(System.String portName,Int32 baudRate,Int32 dataBits,奇偶校验,StopBits stopBits,布尔dtrEnable,布尔rtsEnable,握手握手,Int32 readTimeout,Int32 writeTimeout,Int32 readBufferSize,Int32 writeBufferSize) [0x00000]
at(包装器远程调用带检查)System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System. IO.端口.握手,int,int,int,int)
在 System.IO.Ports.SerialPort.Open () [0x00000]
at (包装器远程调用带检查) System.IO.Ports.SerialPort:Open ()
at HSMScanner.Program.Main (System.String[] args) [0x00000]

3) Macs...

哦天哪,天哪。 Mac(当插入 USB 串行端口并且驱动程序和一切正常时)不会在 GetPortNames() 上返回任何内容。 没什么。 查看 /dev/tty ,只有当设备插入并且具有类似 /dev/tty.usbserial-A7006Ro7 的名称时才会出现额外的设备,不幸的是,使用此名称作为程序的参数,然后使用 serial.open dosnt 似乎有什么影响。

进一步研究它。

Just discovered this thread, and thought I aught to just add my discoveries: randomly, I am also worried about this on a mac. In Windows and Linux (in VS and Mono alike) SerialPort.GetPortNames() return a list, with the following rules:

1) Windows returns a list of strings like Com1, Com4, missing out any which don't exist (USB Serial adapters seem to take a COM number based on the plug they are plugged into, consistantly) From my serial port scanner:

Scanning COM1
Scanning COM4
Scanning Complete

2) Linux returns all possibly tty serial ports that the compiler of the linux distro has enabled. This seems to be about 8 ports, which if you try to open, will throw an exception (from my serial port scanner:

Scanning /dev/ttyS0
Scanning /dev/ttyS1 Port FailedSystem.IO.IOException: I/O Error
at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parity, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBufferSize, Int32 writeBufferSize) [0x00000]
at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int)
at System.IO.Ports.SerialPort.Open () [0x00000]
at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:Open ()
at HSMScanner.Program.Main (System.String[] args) [0x00000]
Scanning /dev/ttyS2 Port FailedSystem.IO.IOException: I/O Error
at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parity, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBufferSize, Int32 writeBufferSize) [0x00000]
at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int)
at System.IO.Ports.SerialPort.Open () [0x00000]
at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:Open ()
at HSMScanner.Program.Main (System.String[] args) [0x00000]
Scanning /dev/ttyS3 Port FailedSystem.IO.IOException: I/O Error
at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parity, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBufferSize, Int32 writeBufferSize) [0x00000]
at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int)
at System.IO.Ports.SerialPort.Open () [0x00000]
at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:Open ()
at HSMScanner.Program.Main (System.String[] args) [0x00000]

3) Macs...

Oh dear oh dear. Macs (when a usb serial port is plugged in and drivers and everything are ok) don't return anything on the GetPortNames(). Nada. Looking in the /dev/tty, the extra devices appear only when the device is plugged in and has names like /dev/tty.usbserial-A7006Ro7 unfortunatly, using this name as an argument to the program followed by serial.open dosnt seem to have any effect.

Looking more into it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文