Я пишу приложение, которое использует 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 (или любые другие процедуры проверки строки). Кроме того, закрытие и повторное открытие порта не только не решает эту проблему, но и перезагрузка программного обеспечения, когда устройство все еще работает, также ничего не делает. Только аппаратная перезагрузка. </p>
Событие My 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.
Мысли? Аппаратное или программное обеспечение связано, я проверяю все, что могу проверить.