Как отправить нулевые символы в последовательный порт с помощью Windows API?

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

  •  23-08-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

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

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

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

Решение

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

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

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

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

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

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

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

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

Ларри

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

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

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

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

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

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

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

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

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