Как я могу отправить нулевые символы на последовательный порт, используя Windows API? - PullRequest
2 голосов
/ 22 декабря 2008

Я работаю над утилитой Windows, которая взаимодействует с некоторым нестандартным оборудованием через стандартный COM-порт. Протокол связи (который находится вне моего контроля) требует от меня передачи и приема необработанных 8-битных байтов данных.

В настоящее время я использую следующую функцию Windows API для отправки данных на COM-порт:

WriteFile(hFile, lpBuffer, numberOfBytesToWrite, ...)

, где hFile - ссылка на правильно открытый COM-порт, а lpBuffer - массив байтов, которые я сохранил в памяти. Код работает отлично, пока на устройство не будет отправлен нулевой символ (ноль ASCII). WriteFile прекращает отправку, как только обнаруживает нулевой символ, поскольку предполагается, что он достиг конца строки. Это происходит, хотя я правильно установил numberOfBytesToWrite.

Как я могу отправлять необработанные данные на COM-порт с помощью Windows API? Я бы предпочел использовать стандартный вызов API, аналогичный WriteFile, но я открыт для предложений.

В настоящее время я использую RapidQ для сборки утилиты, но все, что она делает - это напрямую вызывает функцию Windows API.

Редактировать: Моя установка состоит из ПК с Windows, подключенного через последовательный порт к пользовательскому аппаратному модулю. Модуль имеет небольшой экран, на котором я могу просматривать переданные символы. Я проверил эту настройку с другой сторонней утилитой. Я могу общаться с модулем с помощью этой сторонней программы, и нулевые символы отображаются правильно. В моей собственной программе, когда я использую WriteFile, нулевой символ в любом месте в потоке передачи останавливает отправку остатков потока.

Ответы [ 6 ]

3 голосов
/ 23 декабря 2008

Ранее я занимался программированием последовательного порта Windows и уверен, что смог отправлять нулевые символы через последовательные порты (различные протоколы передачи файлов не работали бы иначе). Я могу придумать два возможных объяснения:

  1. Принимающее устройство печатает полученные данные, используя метод, который останавливается на первом нулевом символе. Как вы определяете, что передающее устройство завершается с первым нулем? Может ли проблема быть где-то еще дальше?
  2. Серийный драйвер не работает. Это довольно маловероятно, но является возможным объяснением. Если вы используете какой-то хитрый сторонний серийный порт и его драйверы, то они могут быть подозрительными. Если вы используете стандартный встроенный последовательный порт с обычными драйверами Windows, то это, вероятно, не проблема.

Я только что взглянул на RapidQ, и есть третье возможное объяснение:

  1. Маршалинг, который RapidQ может выполнять в процессе вызова функций Win32 API, может иметь проблемы со встроенными нулевыми символами в отправляемых данных. Я ничего не знаю о RapidQ, но это еще одно звено в цепочке, которое необходимо учитывать.
1 голос
/ 23 декабря 2008

Если ничего из этого не помогает, вы всегда можете сделать то, что я делаю. Используйте COMM код Грега, чтобы проверить устройство с. Помните Qmodem? :) Очень хороший инструмент для тестирования / отладки последовательных подпрограмм. Вы можете даже использовать Qmodem и простой скрипт Qmodem для чтения COM-порта на другом блоке (или на другом порту в том же блоке) и распечатать шестнадцатеричное значение каждого отправленного символа. Ой, подожди. В Qmodem это встроено. :) Используйте эмуляцию Debug ASCII, и она покажет шестнадцатеричные значения каждого символа, встречающегося через последовательный порт. Затем вы можете хотя бы проверить, правильно ли работает ваш код.

Теперь вопрос. Возвращает ли WriteFile, когда он достигает значения NULL, или он просто сидит и ждет, и никогда не возвращается?

Если оно никогда не вернется, возможно, это не ваш код. WriteFile возвращается только тогда, когда он отправил все dwBytesToWrite или если произошла ошибка. Что-нибудь еще, и это ПЫТАЕТСЯ писать, но на другом конце есть сбой.

1 голос
/ 23 декабря 2008

Я использовал WriteFile в прошлом, и он работал нормально с нулевыми байтами. Я бы покопался в RapidQ, это может быть проблемой.

1 голос
/ 23 декабря 2008

Грег, вероятно, прав, но я бы также проверил настройки вашего com-порта. Убедитесь, что ваши настройки DCB установлены правильно. Посмотрите SetCommState и GetCommState для получения информации.

Обычно Serial равен 8N1, но ваше устройство может использовать другую четность или конфигурацию стоп-бита и т. Д.

Как и Грег, я сам много работал над сериалом, и это часто может быть источником проблем ... Попробуйте поговорить с RS485 и неправильной структурой DCB ... хе ...

Larry

PS: Если у вас его еще нет, я бы порекомендовал себе хороший серийный бокс. У меня есть один где-то в доме, и он покажет вам, что это за сигналы на всех линиях во время всех ваших коммуникаций, и это очень мощный инструмент отладки.

1 голос
/ 23 декабря 2008
0 голосов
/ 14 мая 2019

Чтобы отправить символ NULL через последовательный порт, вы можете использовать функцию setEndOfFile (), передавая обработчик порта в виде файла.

Если у вас слишком много данных NULL для отправки, это, вероятно, не идеально, но это обходной путь.

Подробности функций

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...