2012-06-14 4 views
0

Я застрял в странной проблеме, читая данные из последовательного порта в Java.Чтение ввода-вывода последовательного порта Java

Мне нужно прочитать данные из последовательного порта через метод опроса в потоке, который работает нормально, но у меня есть требование, когда мне нужно записывать данные в последовательный порт и читать ACK обратно. Запись данных на последовательный порт успешна, но я не могу прочитать данные назад. Здесь есть две операции чтения: одна в потоке и одна в основном потоке.

Как только я получаю данные последовательной записи, я приостановил поток, который считывает данные из последовательного порта с использованием флага и снова начинает считывать данные из последовательного порта после того, как запись выполнена, но я не могу читать данные. Я отключил чтение последовательного порта после операции записи и включил поток, который считывает последовательный порт в потоке, здесь я вижу данные ACK из последовательного порта.

Можно ли предположить, что происходит с этой последовательной операцией чтения? Это не буферизованная операция чтения/записи.

+0

Я не уверен, что следую вашей логике. Кажется, вы читаете сразу три разных потока, что не похоже на хорошую идею. – gobernador

+0

Это не три разные потоки, а два потока, один поток, который опроса для последовательного чтения непрерывно и другой в основном потоке, который читается только при выполнении операции записи. –

+1

Хотя я до сих пор не знаю причины этого, я считаю, что понимаю вопрос. Я считаю, что он говорит, что основной поток отправляет команду записи и имеет в нем чтение (ACK-Checker), которое должно увидеть ACK после этого, и имеет чтение в другом потоке (позволяет называть его «общим читателем») выполнять любую другую операцию чтения. Проблема заключается в том, что, когда он пишет из основного потока, ACK-checker не видит ACK.Если он отключает «ACK-checker», тогда «обычный читатель» видит ACK, когда он выполняет свой обычный опрос (чего обычно не следует). Это верно? – Xantham

ответ

0

Я настоятельно рекомендую использовать только один выделенный поток для доступа к считыванию последовательного порта. Самое надежное решение, которое раньше выполнялось обработчиком прерываний, перетаскивая все принятые данные в конечный автомат с потоками. Попытка прочитать последовательный порт из нескольких потоков вызывает проблемы. Последовательный порт IO не заботится о том, чтобы вы «приостановили поток», данные могут быть уже извлечены и потеряны из-за переключения контекста.

Так что просто продолжайте читать то, что входит, и если ожидается ACK и получен, сообщите основной поток через семафор. В грязном зверски упрощенном псевдокоде:

Основной цикл резьбы:

{ 
    serialReaderThread.isAckExpected = true 
    sendWriteCommand(); 
    ackReceivedSemaphore.wait(); 
} 

Последовательная петля читателя нить:

{ 
    readData(); 
    if(isAckExpected && data == ack) { 
    mainThread.ackReceivedSemaphore.notify(); 
    isAckExpected = false 
    } 
} 

Вам нужно установить isAckExpected перед отправкой команды записи, потому что, если ваш последовательный равный достаточно быстро, вы можете получить ответ до того, как ваш sendWriteCommand вернется.

+0

Спасибо Vvtmarin: На самом деле это только в потоке, который я создал для чтения последовательных данных, я ссылаюсь на основной поток, где начинается программа или которая создает поток (основной) –

0

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

У вас будет поток «нормального чтения», который задает данные по потоку чтения. Когда вам нужно выполнить последовательность write/ack, поток, выполняющий запись/ack, временно зарегистрируется в потоке read и переадресует поток данных.

Вам по-прежнему приходится иметь дело с любым чередованием данных (то есть нормальные данные, полученные после запроса на запись, но до получения ack), но это зависит от вашего приложения.