Последовательный порт (rs232) в моно для нескольких платформ

StackOverflow https://stackoverflow.com/questions/434494

Вопрос

Я планирую переписать приложение Win32 (родной C++) на .NET - скорее всего, используя моно, чтобы я мог запускать его на Win32, Linux и Mac.Проблема, которую я пытаюсь решить (на самом деле я разработал только для Win32), - это проблема с определением последовательного порта.Как обычно определить различия в платформах, если предполагается, что существует только один исполняемый файл.В частности, COM-порт определяется в Windows как COM1 или что-то в этом роде (\.\COM), но в Linux они указываются как /dev/ttyS0.

Проверяется ли платформа во время выполнения на наличие этой информации?

Я думаю, единственная разница будет в открытии и закрытии порта.Чтение и письмо одинаковое.

Возможно, это более общий вопрос, поскольку он применим к любым специфичным для платформы вещам в mono/.NET.

Как вы с этим справляетесь?В каком-то строковом ресурсе или файле конфигурации, или жестко закодированном и переключающемся на основе платформы времени выполнения?

Любой пример кода для этого?Обратите внимание: я разработчик C++ и не знаком со всеми классами, доступными в .NET.Есть ли способ получить схему именования последовательного порта из CLR или есть способ получить ОС/платформу из CLR?

было бы неплохо, чтобы CLR могла представлять последовательные порты более независимым образом.Возможно, это невозможно.

Спасибо, Тим

РЕДАКТИРОВАТЬ

Учитывая один ответ, я думаю, мне стоит просто попробовать
Сначала перечислите SerialPort.GetPortNames(), чтобы проверить, работает ли оно.(на обеих платформах)

В Win32 для более высоких номеров портов и USB-ключа это не так просто, как базовое перечисление COM-портов.

О результатах сообщу здесь.

Это было полезно?

Решение

Только что обнаружил эту тему и подумал, что мне стоит просто добавить свои открытия:случайно, меня тоже это беспокоит на Mac.В Windows и Linux (как в VS, так и в Mono) SerialPort.GetPortNames() возвращает список со следующими правилами:

1) Windows возвращает список строк, таких как Com1, Com4, пропуская все несуществующие (похоже, последовательные USB-адаптеры постоянно принимают номер COM в зависимости от штекера, к которому они подключены). Из моего сканера последовательного порта:

Scanning COM1 Scanning COM4 Scanning Complete

2) Linux возвращает все возможные последовательные порты tty, которые включил компилятор дистрибутива Linux.Кажется, это около 8 портов, которые, если вы попытаетесь открыть, выдадут исключение (из моего сканера последовательных портов:

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) Маки...

О, дорогая, о, дорогая.Компьютеры Mac (когда последовательный порт USB подключен, драйверы и все в порядке) не возвращаются что-либо в GetPortNames().Нада.Заглянув в /dev/tty, дополнительные устройства появляются только тогда, когда устройство подключено и имеет имена типа /dev/tty.usbserial-A7006Ro7. К сожалению, использование этого имени в качестве аргумента программы, за которым следует Serial.open, похоже, не работает. иметь какой-либо эффект.

Присматриваюсь к этому больше.

Другие советы

В .Net вам нужны System.IO.Ports.Такие имена, как «COM1» и «/dev/ttyS0», являются случайными именами ОС.Зачем вам их жестко закодировать?Пользователь должен просто выбрать один из списка доступных портов.

Очевидно, вы определяете этот список во время выполнения.Фактически, при использовании адаптеров USB-последовательный порт вы можете рассмотреть возможность того, что пользователь только после запуска вашей программы обнаружит, что он забыл подключить свой адаптер USB-последовательный порт.Это означает, что вам следует перечитывать этот список каждый раз, когда вы открываете диалоговое окно конфигурации.USB-адаптер, скорее всего, не COM1, кстати.

(Я не могу ручаться за качество реализации SerialPort в Mono.Быстрый поиск в Google меня немного забеспокоил, но проверьте сами)

Я посмотрел на это, и кажется, что монокод для перечисления последовательных портов не будет работать ни на чем, кроме 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]+)

Я также не могу сказать, что в восторге от того, как он выбирает, под какой ОС он работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top