Я пишу приложение, использующее OpenNETCF.IO.Serial (открытый исходный код, см. серийный код здесь) для его последовательной связи на устройстве Windows CE 6.0. Это приложение написано на C # в Compact Framework 2.0. Я не верю, что проблема, которую я собираюсь описать, конкретно связана с этими деталями, но может оказаться, что я ошибаюсь в этом отношении.
Проблема, с которой я сталкиваюсь, заключается в том, что по-видимому случайным образом (читается как: прерывистая проблема, которую я пока не могу надежно воспроизвести) данные не могут быть переданы или получены до тех пор, пока само устройство не будет перезагружено. Устройство Windows CE взаимодействует с системой, в которой запущено совершенно другое приложение. Перезагрузка этой другой системы и отключение / повторное подключение кабелей связи, похоже, не решает эту проблему, а только перезагрузка устройства Windows CE.
Единственным признаком возникновения этой проблемы является отсутствие события TxDone от запуска OpenNETCF (ищите «TxDone ();» в классе OpenNETCF.IO.Serial) и отсутствие данных, когда я точно знаю, что подключенный система отправляет данные.
Любое символьное значение от 1 до 255 (0x01 - 0xFF) может быть отправлено и получено в нашей последовательной связи. Нулевые значения отбрасываются.
Мои настройки последовательного порта: 38400 бод, 8 бит данных, без контроля четности, 1 стоповый бит (38400, 8n1). Я установил размер входного и выходного буфера равным 256 байтам. Событие DataReceived происходит всякий раз, когда мы получаем 1 или более символов, а передача происходит, когда в выходном буфере 1 или более байтов, поскольку сообщения имеют переменную длину.
Рукопожатие не используется. Поскольку это RS422, используются только 4 сигнала: RX +, RX-, TX +, TX-.
Я получаю событие «DataReceived», я читаю все данные из входного буфера и создаю свой собственный буфер в своем коде, чтобы проанализировать его на досуге вне события DataReceived. Когда я получаю командное сообщение, я отправляю быстрое сообщение с подтверждением. Когда другая система получает командное сообщение от устройства Windows CE, она отправляет обратно сообщение быстрого подтверждения. Сообщения с подтверждением не получают дальнейших ответов, поскольку они предназначены для простого «Ага, понятно». В моем коде я получаю / передаю через несколько потоков, поэтому я использую ключевое слово lock, чтобы не передавать несколько сообщений одновременно в нескольких потоках. Двойная проверка кода показала, что я не зацикливаюсь на каких-либо блокировках.
На данный момент мне интересно, постоянно ли я упускаю что-то очевидное о том, как работает последовательная связь, например, если мне нужно установить некоторую переменную или свойство, а не просто читать из входного буфера, когда он не пуст, и записывать в буфер передачи.
Любые идеи, варианты для проверки, предложения, идеи и т. Д. Приветствуются. Это то, с чем я боролся самостоятельно в течение нескольких месяцев, я надеюсь, что ответы или комментарии, которые я получаю здесь, могут помочь в решении этой проблемы. Заранее спасибо.
Редактировать, 24.02.2011:
(1) Я могу воссоздать только ошибку при загрузке системы, с которой обменивается данными устройство Windows CE, а не при каждой загрузке. Я также посмотрел на сигналы, синфазное напряжение колеблется, но амплитуда шума, возникающего при загрузке системы, кажется, не связана с тем, возникает проблема или нет, я видел, что размах напряжения 25 В не вызывает проблем, когда пик 5 В -тогда проблема возникла снова).
Проблема продолжает звучать, все больше и больше связана с оборудованием, но я пытаюсь выяснить, что может вызвать симптомы, которые я вижу, поскольку ни одно из оборудования на самом деле не выходит из строя или не выключается , по крайней мере, там, где я смог измерить сигналы. Приношу свои извинения, но я не могу назвать артикулы компонентов оборудования, поэтому, пожалуйста, не спрашивайте, какие компоненты используются.
(2) В соответствии с предложением @ctacke, я обеспечил, чтобы все передачи проходили через одно и то же место для удобства обслуживания, безопасность потоков, которую я ввел, по существу выглядит следующим образом:
lock(transmitLockObj)
{
try
{
comPort.Output = data;
}
[various catches and error handling for each]
}
(3) Получение ошибок UART OVERRUN в тесте, где отправлялись и принимались ‹10 байтов с интервалом времени около 300 мсек на скорости 38400 бод. Как только он получает ошибку, он переходит к следующей итерации цикла, НЕ запускает ReadFile и НЕ запускает событие TxDone (или любые другие процедуры проверки строк). Кроме того, не только закрытие и повторное открытие порта ничего не делает для решения этой проблемы, но и перезагрузка программного обеспечения при работающем устройстве тоже ничего не дает. Только аппаратная перезагрузка.
Мое событие DataReceived выглядит следующим образом:
try
{
byte[] input = comPort.Input; //set so Input gets FULL RX buffer
lock(bufferLockObj)
{
for (int i = 0; i < input.Length; i++)
{
_rxRawBuffer.Enqueue(input[i]);
//timer regularly checks this buffer and parses data elsewhere
//there, it is "lock(bufferLockObj){dataByte = _rxRawBuffer.Dequeue();}"
//so wait is kept short in DataReceived, while remaining safe
}
}
}
catch (Exception exc)
{
//[exception logging and handling]
//hasn't gotten here, so no point in showing
}
Однако сразу после истечения времени ожидания вызова WriteFile в первый раз в тесте я начал получать ошибки UART OVERRUN. Я честно не вижу, как мой код вызывает состояние UART OVERRUN.
Мысли? Что касается оборудования или программного обеспечения, я проверяю все, что могу.