- Com порт консоль windows
- АСУТП и интеллектуальная начинка приборов
- вторник, 31 марта 2015 г.
- Работа с COM портом из командной строки. Мониторинг
- COM-порт в Windows (программирование)
- Содержание
- Открытие порта [ править ]
- lpFileName [ править ]
- dwDesiredAccess [ править ]
- dwShareMode [ править ]
- lpSecurityAttributes [ править ]
- dwCreationDistribution [ править ]
- dwFlagsAndAttributes [ править ]
- hTemplateFile [ править ]
- Закрытие порта [ править ]
- Пример открытия/закрытия на языке C [ править ]
- Структура DCB [ править ]
- DCBlength [ править ]
- BaudRate [ править ]
- fBinary [ править ]
- fParity [ править ]
- fOutxCtsFlow [ править ]
- fOutxDsrFlow [ править ]
- fDtrControl [ править ]
- fDsrSensitivity [ править ]
- fTXContinueOnXoff [ править ]
- fOutX [ править ]
- fInX [ править ]
- fErrorChar [ править ]
- fNull [ править ]
- fRtsControl [ править ]
- fAbortOnError [ править ]
- fDummy2 [ править ]
- wReserved [ править ]
- XonLim [ править ]
- XoffLim [ править ]
- ByteSize [ править ]
- Parity [ править ]
- StopBits [ править ]
- XonChar [ править ]
- XoffChar [ править ]
- ErrorChar [ править ]
- EofChar [ править ]
- EvtChar [ править ]
- wReserved1 [ править ]
- Замечания [ править ]
- Заполнение структуры DCB [ править ]
- Структура COMMTIMEOUTS [ править ]
- Заполнение структуры COMMTIMEOUTS [ править ]
- Пример настройки порта [ править ]
- Структура COMMPORT [ править ]
- Стандартный диалог настройки порта [ править ]
- Выделение памяти для структуры COMMPORT [ править ]
- Прием и передача данных [ править ]
- Сброс порта [ править ]
- Пример настройки порта и выполнения чтения/записи данных [ править ]
Com порт консоль windows
Мне часто нужно посылать короткие строки символов в последовательный порт на операционной системе Windows (перевод статьи [1]). Это можно использовать для отправки команд роботу или в другие устройства, основанным на микроконтроллерах. Для соединения с устройством можно использовать аппаратный преобразователь USB-to-serial, которые в обилии можно найти на сайтах AliExpress, Ebay и dx.com. Для отправки символов есть удобная утилита SerialSend [2], но также можно использовать встроенные команды Windows: echo, set и mode.
К примеру, нужно послать строку «hello» в COM1 (имя первого последовательного порта Windows). Для этого можно просто ввести в консоли cmd.exe следующую команду:
Команда echo обычно используется для отображения строк в консоли командной строки, когда нужно вывести какое-нибудь информационное сообщение из скрипта команд *.BAT или *.CMD. Однако в этом примере с помощью символа > применено перенаправление вывода в специальный файл COM1, который в действительности не файл на диске, а последовательный порт. По этой причине строка «hello» отправляется в последовательный порт вместо экрана консоли.
Но для такого вывода текста в последовательный порт есть несколько препятствий:
• Нужно заранее знать номер COM-порта, который хотите использовать. Если Вы используете преобразователь USB-to-serial, то этот номер может неожиданно поменяться, особенно если Вы подключили его в другой разъем USB (программа SerialSend [2] предоставляет простой альтернативный метод отправки строк в любой доступный COM-порт с самым высоким порядковым номером, что может быть очень полезным).
• Строка, которая отправляется в нашем примере, в действительности имеет длину 8 байт, потому что она включает 1 байт завершающего пробела (код ASCII 0x20) плюс символ возврата каретки (CR, код 0x0D) и перевода строки (LF, код 0x0A).
• Отправлять можно только обычные символы текста. К примеру, произвольные байты с кодами 0x00 .. 0x19 отправлять не получится, на это способна только утилита SerialSend [2].
• Последовательный порт, который Вы хотите использовать, может быть настроен не на ту скорость, которая Вам нужна. В таком случае дополнительно нужно использовать команду mode, чтобы сконфигурировать скорость baudrate (и/или другие параметры фрейма последовательного протокола).
• COM-порты с большими номерами могут быть не распознаны для такого примера, но для их использования есть обходной маневр, описанный ниже.
Следующий пример — более надежный аналог команды из примера выше:
Эта команда может выглядеть поначалу довольно непонятной, давайте разберем её по частям.
Команда set обычно используется для установки значения для так называемой переменной окружения (environment variable). Например, следующая команда должна использоваться для установки переменной окружения с именем x в значение строки «sunshine»:
Когда в команде set используется ключ /p, то команда set выводит приглашение для пользователя, чтобы он ввел значение для устанавливаемой переменной окружения. Приглашение отображается на экране в виде строки, предоставленной в команде. Например:
Конечно, нас в сущности не интересует установка значения переменной x как таковой, сейчас это просто средство для достижения другой цели. Все, что мы хотим — вывести строку «hello» без символов CR и LF, и команда set только лишь предоставляет способ для решения этой задачи.
Мы не хотим, чтобы команда set остановилась на ожидании ввода пользователя, чтобы он ввел значение для переменной x, для этого команда set перенаправлена на ввод из nul (т. е. нет ввода как такового, вместо обычного ввода, который обычно происходил бы из консоли). Это означает, что команда сразу завершит работу, вместо того, чтобы ожидать ввода пользователя. Перенаправление ввода осуществляется символом
АСУТП и интеллектуальная начинка приборов
Добро пожаловать в киберблог радиоинженера и программиста, позывной UR3QQJ. Мой многолетний опыт затрагивает такие области, как промавтоматизация, IoT и руководство людьми. Второе направление — аудит ИС в области безопасности. Третье — ЦОС в области радиолокации. Экспертное консультирование и нестандартные решения? Без проблем. Приглашаю на канал.
вторник, 31 марта 2015 г.
Работа с COM портом из командной строки. Мониторинг
. вот все-таки батники незаслуженно игнорируются любителями высокоуровневых языков, а тем не менее даже на них можно решить задачи по мониторингу не только удаленных хостов, но и мониторинга COM-порта, что под DOS, что под Windows. К примеру, возникла задача реагирования (запуска какого-либо приложения) на приход сигнала на один из пинов, кнопка к примеру (выставить DTR тот же и замкнуть с CTS).
Напомню еще раз распиновку COM-порта:
Номер вывода Наименование Характер сигнала Сигнал
1 DCD Входной Data carrier detect
2 RxD Выходной Transmit data
3 TxD Входной Receive data
4 DTR Выходной Data terminal ready
5 GND — Ground
6 DSR Входной Data set ready
7 RTS Выходной Request to send
8 CTS Входной Clear to send
9 RI Входной Ring indicator
Нам нужно управлять состоянием устройства ввода-вывода. Одной из таких команд — mode (синтаксис см. по mode /?):
Что мы видим? Видим возможность установки скорости, паритета, служебных пинов, паритета и иже с ними. А что нам даст обращение (mode com1) к конкретному COM-порту? А вот сие даст:
Cостояние пинов и настроек порта. Можем прочитать? Можем. Для этого воспользуемся FIND=»параметр» (важно точное указание всех знаков):
@ echo off
mode com1 dtr=on > nul
:m1
mode com1 | find «CTS: ON» > nul
if errorlevel=1 goto m1
if errorlevel=0 start notepad.exe
Передача в COM-порт
Отослать число в COM порт через ECHO (служит для вывода текста в стандартный поток вывода информации):
COM-порт в Windows (программирование)
Написать программу, управляющую устройством через COM-порт, для MS-DOS не так сложно. С платформой Win32 дело обстоит сложнее. Но только на первый взгляд. Конечно напрямую работать с регистрами портов нельзя, Windows это не позволяет, зато можно не обращать внимания на тонкости различных реализаций (i8251, 16450, 16550A) и не возиться с обработкой прерываний.
Содержание
Открытие порта [ править ]
С последовательными и параллельными портами в Win32 работают как с файлами. Для открытия порта используется функция CreateFile . Эта функция предоставляется Win32 API. Ее прототип выглядит так:
lpFileName [ править ]
Указатель на строку с именем открываемого или создаваемого файла. Формат этой строки может быть очень «хитрым». В частности можно указывать сетевые имена для доступа к файлам на других компьютерах. Можно открывать логические разделы или физические диски и работать в обход файловой системы.
Последовательные порты имеют имена «COM1», «COM2», «COM3», «COM4», «COM5», «COM6», «COM7», «COM8», «COM9». Для доступа к портам, чей номер больше 9, необходимо указывать имя порта как «\\.\COMx», где x — номер порта. Например, «\\.\COM72» (в нотации языка C/C++ строка будет выглядеть «\\\\.\\COM72»). Такой синтаксис подходит для любого номера порта. Точно так же они назывались в MS-DOS. Параллельные порты называются «LPT1», «LPT2» и так далее.
dwDesiredAccess [ править ]
Задает тип доступа к файлу. Возможно использование следующих значений:
- 0 Опрос атрибутов устройства без получения доступа к нему.
- GENERIC_READ Файл будет считываться.
- GENERIC_WRITE Файл будет записываться.
- GENERIC_READ|GENERIC_WRITE Файл будет и считываться и записываться.
dwShareMode [ править ]
Задает параметры совместного доступа к файлу. Коммуникационные порты нельзя делать разделяемыми, поэтому данный параметр должен быть равен 0.
lpSecurityAttributes [ править ]
Задает атрибуты защиты файла. Поддерживается только в Windows NT. Однако при работе с портами должен в любом случае равняться NULL .
dwCreationDistribution [ править ]
Управляет режимами автосоздания, автоусечения файла и им подобными. Для коммуникационных портов всегда должно задаваться OPEN_EXISTING .
dwFlagsAndAttributes [ править ]
Задает атрибуты создаваемого файла. Также управляет различными режимами обработки. При работе с портом этот параметр должен быть или равным 0 , или FILE_FLAG_OVERLAPPED . Нулевое значение используется при синхронной работе с портом, а FILE_FLAG_OVERLAPPED при асинхронной, или, другими словами, при фоновой обработке ввода/вывода. Подробнее про асинхронный ввод/вывод я расскажу позже.
hTemplateFile [ править ]
Задает описатель файла-шаблона. При работе с портами всегда должен быть равен NULL .
При успешном открытии файла, в данном случае порта, функция возвращает дескриптор ( HANDLE ) файла. При ошибке [[| INVALID HANDLE VALUE ]]. Код ошибки можно получитить вызвав функцию [[| GetLastError ]].
Закрытие порта [ править ]
Открытый порт должен быть закрыт перед завершением работы программы. В Win32 закрытие объекта по его дескриптору выполняет функция CloseHandle :
При успешном завершении функция возвращает не нулевое значение, при ошибке нуль.
Пример открытия/закрытия на языке C [ править ]
В данном примере открывается порт СОМ2 для чтения и записи, используется синхронный режим обмена. Проверяется успешность открытия порта, при ошибке выводится сообщение и программа завершается. Если порт открыт успешно, то он закрывается.
Структура DCB [ править ]
Основные параметры последовательного порта описываются структурой DCB . Временные параметры — структурой COMMTIMEOUTS . Существует еще несколько информационных и управляющих структур, но они используются реже. Настройка порта заключается в заполнении управляющих структур и последующем вызове функций настройки.
Основную информацию содержит структура DCB :
Эта структура содержит почти всю управляющую информацию, которая в реальности располагается в различных регистрах последовательного порта.
DCBlength [ править ]
Задает длину, в байтах, структуры DCB . Используется для контроля корректности структуры при передаче ее адреса в функции настройки порта.
BaudRate [ править ]
Скорость передачи данных. Возможно указание следующих констант: CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400, CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400, CBR_56000, CBR_57600, CBR_115200, CBR_128000, CBR_256000 . Эти константы соответствуют всем стандартным скоростям обмена. На самом деле, это поле содержит числовое значение скорости передачи, а константы просто являются символическими именами. Поэтому можно указывать, например, и CBR_9600 , и просто 9600 . Однако рекомендуется указывать символические константы, поскольку при компиляции программы проверяется корректность их имен.
fBinary [ править ]
Включает двоичный режим обмена. Win32 не поддерживает недвоичный режим, поэтому данное поле всегда должно быть равно 1 , или логической константе TRUE (что предпочтительней). В Windows 3.1, если это поле было равно FALSE , включался текстовый режим обмена. В этом режиме поступивший на вход порта символ, заданный полем EofChar , свидетельствовал о конце принимаемых данных.
fParity [ править ]
Включает режим контроля четности. Если это поле равно TRUE , то выполняется проверка четности, при ошибке, в вызывающую программу, выдается соответствующий код завершения.
fOutxCtsFlow [ править ]
Включает режим слежения за сигналом [[| CTS ]]. Если это поле равно [[| TRUE ]] и сигнал [[| CTS ]] сброшен, передача данных приостанавливается до установки сигнала CTS . Это позволяет подключеному к компьютеру прибору приостановить поток передаваемой в него информации, если он не успевает ее обрабатывать.
fOutxDsrFlow [ править ]
Включает режим слежения за сигналом [[| DSR ]]. Если это поле равно TRUE и сигнал DSR сброшен, передача данных прекращается до установки сигнала DSR .
fDtrControl [ править ]
Задает режим управления обменом для сигнала [[| DTR ]]. Поле может принимать следующие значения:
- DTR_CONTROL_DISABLE Сигнал DTR снимается при открытии порта. У открытого порта может быть изменён функцией EscapeCommFunction.
- DTR_CONTROL_ENABLE Сигнал DTR устанавливается при открытии порта. У открытого порта может быть изменён функцией EscapeCommFunction.
- DTR_CONTROL_HANDSHAKE Сигнал DTR автоматически устанавливается/снимается в ходе работы с портом. Не может быть изменён функцией EscapeCommFunction.
fDsrSensitivity [ править ]
Задает чувствительсть коммуникационного драйвера к состоянию линии [[| DSR ]]. Если это поле равно TRUE , то все принимаемые данные игнорируются драйвером (коммуникационный драйвер расположен в операционной системе), за исключением тех, которые принимаются при установленом сигнале DSR .
fTXContinueOnXoff [ править ]
Задает, прекращается ли передача при переполнении приемного буфера и передаче драйвером символа XoffChar . Если это поле равно TRUE , то передача продолжается, несмотря на то, что приемный буфер содержит более XoffLim символов и близок к переполнению, а драйвер передал символ XoffChar для приостановления потока принимаемых данных. Если поле равно FALSE , то передача не будет продолжена до тех пор, пока в приемном буфере не останется меньше XonLim символов и драйвер не передаст символ XonChar для возобновления потока принимаемых данных. Таким образом это поле вводит некую зависимость между управлением входным и выходным потоками информации.
fOutX [ править ]
Задает использование XON/XOFF управления потоком при передаче. Если это поле равно TRUE , то передача останавливается при приеме символа XoffChar , и возобновляется при приеме символа XonChar .
fInX [ править ]
Задает использование XON/XOFF управления потоком при приеме. Если это поле равно TRUE , то драйвер передает символ XoffChar , когда в приемном буфере находится более XoffLim , и XonChar , когда в приемном буфере остается менее XonLim символов.
fErrorChar [ править ]
Указывает на необходимость замены символов с ошибкой четности на символ задаваемый полем ErrorChar . Если это поле равно TRUE , и поле fParity равно TRUE , то выполняется замена.
fNull [ править ]
Определяет действие выполняемое при приеме нулевого байта. Если это поле TRUE , то нулевые байты отбрасываются при передаче.
fRtsControl [ править ]
Задает режим управления потоком для сигнала RTS. Поле может принимать следующие значения:
- RTS_CONTROL_DISABLE Сигнал RTS снимается при открытии порта. У открытого порта может быть изменён функцией EscapeCommFunction.
- RTS_CONTROL_ENABLE Сигнал RTS устанавливается при открытии порта. У открытого порта может быть изменён функцией EscapeCommFunction.
- RTS_CONTROL_HANDSHAKE Сигнал RTS автоматически устанавливается/снимается в ходе работы с портом. Не может быть изменён функцией EscapeCommFunction. Сигнал RTS устанавливается, когда приемный буфер заполнен менее, чем на половину, и снимается, когда буфер заполняется более чем на три четверти.
- RTS_CONTROL_TOGGLE Задаёт, что сигнал RTS установлен, когда есть данные для передачи. Когда все символы из передающего буфера переданы, сигнал снимается.
fAbortOnError [ править ]
Задает игнорирование всех операций чтения/записи при возникновении ошибки. Если это поле равно TRUE , драйвер прекращает все операции чтения/записи для порта при возникновении ошибки. Продолжать работать с портом можно будет только после устранения причины ошибки и вызова функции ClearCommError.
fDummy2 [ править ]
Зарезервировано и не используется.
wReserved [ править ]
Не используется, должно быть установлено в 0 .
XonLim [ править ]
Задает минимальное число символов в приемном буфере перед посылкой символа XON .
XoffLim [ править ]
Определяет максимальное количество байт в приемном буфере перед посылкой символа XOFF . Максимально допустимое количество байт в буфере вычисляется вычитанием данного значения из размера приемного буфера в байтах.
ByteSize [ править ]
Определяет число информационных бит в передаваемых и принимаемых байтах. Число информационных бит может быть в диапазоне от 4 до 8 .
Parity [ править ]
Определяет выбор схемы контроля четности. Данное поле должно содержать одно из следующих значений:
- EVENPARITY Дополнение до четности
- MARKPARITY Бит четности всегда 1
- NOPARITY Бит четности отсутствует
- ODDPARITY Дополнение до нечетности
- SPACEPARITY Бит четности всегда 0
StopBits [ править ]
Задает количество стоповых бит. Поле может принимать следующие значения:
- ONESTOPBIT Один стоповый бит
- ONE5STOPBIT Полтора стоповых бита
- TWOSTOPBITS Два стоповых бита
XonChar [ править ]
Задает символ XON используемый как для приема, так и для передачи. Обычно 0x11 ( 17 ).
XoffChar [ править ]
Задает символ XOFF используемый как для приема, так и для передачи. Обычно 0x13 ( 19 ).
ErrorChar [ править ]
Задает символ, использующийся для замены символов с ошибочной четностью.
EofChar [ править ]
Задает символ, использующийся для сигнализации о конце данных.
EvtChar [ править ]
Задает символ, использующийся для сигнализации о событии.
wReserved1 [ править ]
Зарезервировано и не используется.
Замечания [ править ]
Если структура DCB содержит конфигурацию для последовательного порта, совместимого с 8250, то к значениям полей ByteSize и StopBits применяются следующие ограничения:
- Количество информационных бит должно быть от 5 до 8 .
- Не допускается использование 5 информационных бит с 2 стоповыми битами, также как 6 , 7 или 8 информационных бит с 1,5 стоповыми битами.
Заполнение структуры DCB [ править ]
Структура COMMTIMEOUTS [ править ]
ReadIntervalTimeout — время в миллисекундах, задающее максимальное время, для интервала между поступлением двух символов по линии связи. Если интервал между поступлением каких-либо двух символов будет больше этой величины, операция ReadFile завершается и любые буферизированные данные возвращаются.
Чтобы операция ReadFile немедленно возвращала управление со всеми полученными данными (асинхронный режим) следует задавать следующие значения:
ReadTotalTimeoutMultiplier — Множитель, используемый, чтобы вычислить полный период времени простоя для операций чтения, в миллисекундах. Для каждой операции чтения, это значение умножается на затребованное число байтов, которые читаются.
ReadTotalTimeoutConstant — Константа, используемая, чтобы вычислить полный (максимальный) период времени простоя для операций чтения, в миллисекундах. Для каждой операции чтения, это значение добавляется к произведению члена структуры ReadTotalTimeoutMultiplier и прочитанного числа байтов.
Значение нуля и для члена ReadTotalTimeoutMultiplier, и для члена ReadTotalTimeoutConstant указывает, что полное время простоя не используются для операций чтения.
WriteTotalTimeoutMultiplier — Множитель, используемый, чтобы вычислить полный период времени простоя для операций записи, в миллисекундах. Для каждой операции записи, это значение умножается на число записываемых байтов.
WriteTotalTimeoutConstant — Константа, используемая, чтобы вычислить полный период времени простоя для операций записи, в миллисекундах. Для каждой операции записи, это значение добавляется к произведению члена структуры WriteTotalTimeoutMultiplier и записанного числа байтов.
Значение нуля и для члена WriteTotalTimeoutMultiplier, и для члена WriteTotalTimeoutConstant указывает, что полное время простоя не используются для операций записи.
Заполнение структуры COMMTIMEOUTS [ править ]
Вариант 1: (максимальная задержка при чтении и записи = TIMEOUT)
Вариант 2: Инициализация значениями (без задержки при чтении)
Пример настройки порта [ править ]
Структура COMMPORT [ править ]
Стандартный диалог настройки порта [ править ]
Для настройки параметров COM — порта может быть вызвано штатное окно Windows. Вызов осуществляется функцией CommConfigDialog(), которая в качестве параметров принимает имя настраиваемого порта, хендл родительского окна и указатель на структуру COMMCONFIG. Следует отметить, что для корректного вызова окна, структура COMMCONFIG должна быть заполнена значениями заранее. Настройку структуры можно выполнить вручную или при помощи функции GetCommConfig(). Например:
Выделение памяти для структуры COMMPORT [ править ]
Прием и передача данных [ править ]
Прием и передача данных для последовательного порта может выполнятся в синхронном или асинхронном режимах. Асинхронный режим позволяет реализовать работу по событиям, в то время как синхронный лишен этой возможности, но является более простым в реализации. Для работы в синхронном режиме, порт должен быть открыт следующим образом:
Предпоследний параметр dwFlagsAndAttributes должен быть равен 0. После успешного открытия порта, данные могут быть считаны или записаны при помощи функций ReadFile() и WriteFile().
Функция ReadFile/WriteFile осуществляет чтение/запись из файла (устройства) начиная с текущей позиции после окончания чтения обновляет указатель в файле.
Недостатком этого способа является то, что вызывая функцию ReadFile(), мы не знаем есть ли данные для чтения. Можно циклически проверять их наличие, но это приводит к дополнительным расходам времени ЦП. Поэтому на практике часто удобней использовать асинхронный режим. Для этого при вызове функции CreateFile() параметр dwFlagsAndAttributes должен быть равен FILE_FLAG_OVERLAPPED.
Далее, необходимо настроить реакцию порта на события при помощи функции SetCommMask() и используя функции WaitCommEvent() и WaitForSingleObject() ожидать событие или тайм аут. Например:
Сброс порта [ править ]
Пример настройки порта и выполнения чтения/записи данных [ править ]
Код для работы с COM-портом. Многострадальный, соответственно относительно простой и понятный, при этом обходит основные подводные камни. Надеюсь, может быть полезен.