Russian Qt Forum
Ноябрь 23, 2024, 02:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Поясните по COM портам один вопрос  (Прочитано 5468 раз)
skandinavijos
Гость
« : Январь 11, 2013, 10:54 »

Я всегда думал, что писать в COM порт и читать из него надо из двух разных потоков, т.е. нельзя, в частности, записать в порт и тут же в этой же функции прочитать ответ от устройства. Так же утверждает один знакомый программист (пишет прошивки для микроконтроллеров и иногда драйвера), а другой знакомый программист (модули для ядра Linux и все в таком духе, т.е. оба вроде как компетентны) - утверждает, что это возможно в одной функции. Вопрос кто прав? Собственно, я к ним обратился за помощью, когда пытался писать и читать из одной функции и не читалось, а в следующем вызове функции читался ответ на предыдущий запрос (ну не работал, я с портами никогда раньше, может это и очевидно кому-то). Но вчера при использовании boost:asio у меня получалось читать и писать в одной одной функции, но через какое-то время эффект пропал (когда я, обрадованный, добавил пару плюшек в код. возврат к первоначальному коду не помог) и стало максимум читаться только несколько байт. Можете пояснить ситуацию немножко? Может не в тему форума, но люди здесь знающие, а регистрироваться неохота где-то еще.
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #1 : Январь 11, 2013, 11:05 »

Как то тут всё в кучу - потоки, порты, функции. Каша какая-то.
Правы оба знакомых. Всё зависит от того как функция работы с портом реализована.
Вообще различают два метода работы с COM портами - синхронный (блокирующий) и асинхронный (неблокирующий). При синхронном методе выполнение функции на время операций ввода/вывода с портом приостанавливается, при асинхронном - нет. Дальше всё уже зависит от программиста какой метод он любит больше, такой и использует.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Январь 11, 2013, 12:02 »

Цитировать
Я всегда думал, что писать в COM порт и читать из него надо из двух разных потоков, т.е. нельзя, в частности, записать в порт и тут же в этой же функции прочитать ответ от устройства.
Можно так делать, кто тебе мешает?
Код
C++ (Qt)
void MyCoolIoFunctionWin() {
   ...
   if (WriteFile(hCom, ...)) {
       if (ReadFile(hCom, ...) {
           // do processing data
       } else {
           // reading i/o error
       }
   } else {
       // writing i/o error
   }
   ...
}
 
void MyCoolIoFunctionUnix() {
   ...
   if (write(fd, ...)) {
       if (read(fd, ...) {
           // do processing data
       } else {
           // reading i/o error
       }
   } else {
       // writing i/o error
   }
   ...
}
 

Но такой подход чаще используется в блокирующем режиме (как выше уже сказали), т.е. ф-ции чтения/записи не завершатся
пока не будет произведена операция чтения/записи. В этом случае, если тебе необходимо одновременно отдельно и читать
и писать в порт - то ДА, тут нужно использовать отдельные потоки для этого, т.к. ф-ции чтения/записи заблокируют текущий
контекст.

Но это не является особенностью именно портов, это особенность вообще, для всех операций ввода/вывода!!!

Блокирующий/неблокирующий режим порта (и любого другого коммуникационного ресурса) устанавливается при открытии этого порта,
а также при его конфигурировании.

Например, для COM-порта в Win это определяется в CreateFile(), а также при установке некоторых параметров в CommTimeouts... В *nix - аналогично.

Если же ты откроешь порт (ресурс) в неблокирующем режиме, то ф-ции чтения/записи не будут блокироваться, а сразу возвратят какой-то
результат без ожидания. В этом случае потоки не нужны. Результат операции можно получить позже либо через callback (оно само вызовется
в нужный момент) либо поймав event (или не поймав, если результат не нужен) этой операции.

Как-то так.

UPD: Но опять же повторюсь, концепция блокирующего/неблокирующего ввода/вывода относится в любому ресурсу, будь по Pipe, File, Socket
и т.п., а не только к COM-портам т.е. это общая хрень.  Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Ubuntu_linux
Гость
« Ответ #3 : Январь 15, 2013, 15:23 »

Давно уже не работал с портами, но все же, там же два канала (провода) Tx, Rx, так что теоретически запросто можно и читать и писать одновременно, как бы... Тут уже дело в апи и ос.
Записан
Bepec
Гость
« Ответ #4 : Январь 15, 2013, 15:41 »

Кхм... Ubuntu_linux  это зависит от протокола передачи данных.

Если RS-422 - тогда да, там 4 провода, rx + rx- tx+ tx-. Приём передача возможны.
Если RS-485 двухпроводный, то только синхронная передача, бывают коллизии. Там 2 провода R+ R-, по второму идёт инвертированный сигнал.
Если RS-485 четырёхпроводный - тогда так же как и 422. Приём и передача.

Ну как то так ) Хотя ещё дофига протоколов вроде есть Веселый
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #5 : Январь 22, 2013, 08:35 »

Если RS-485 двухпроводный, то только синхронная передача, бывают коллизии. Там 2 провода R+ R-, по второму идёт инвертированный сигнал.

А кто в 485 мешает одновременно принимать и передавать? У меня протокол реализован с контролем передачи. Т.е. разрешаю микросхеме-формирователю 485 и прием и передачу одновременно, передаю данные и тут же их читаю. Сверяю переданный пакет с принятым. Если совпало, то коллизий на шине нет.

Давно уже не работал с портами, но все же, там же два канала (провода) Tx, Rx, так что теоретически запросто можно и читать и писать одновременно, как бы... Тут уже дело в апи и ос.
+1
Записан
lesav
Частый гость
***
Offline Offline

Сообщений: 235


qnx.org.ru


Просмотр профиля WWW
« Ответ #6 : Январь 22, 2013, 21:15 »

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

... разрешаю микросхеме-формирователю 485 и прием и передачу одновременно, передаю данные и тут же их читаю. Сверяю переданный пакет с принятым. Если совпало, то коллизий на шине нет.
"Мартышкин труд" проверять произнесенное с услышанным.  При любой коллизии вы получите правильное сообщение, т.к. внутреннее сопротивление передатчика несоизмеримо мало по сравнению с сопротивлением линии (но скорее всего чтение своего сообщение вы производите из буфера драйвера, в котором включен режим эха).

Идеальное решение для борьбы с коллизиями - выжидать паузу тишины в линии перед отправкой (это только в протоколе связи Мастер-Слэйв), ну или жестко придерживаться спецификацией протокола
Записан

juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #7 : Январь 23, 2013, 10:44 »

мартышкин - не мартышкин. Это протокол. В ТЗ чётоко прописано работа протокола. Это его специфика, её и придерживаюсь. и нормально работает такая защита от коллизии.

В КАН подобная защита, но аппаратная.

Цитировать
но скорее всего чтение своего сообщение вы производите из буфера драйвера, в котором включен режим эха
ну тут даже не чего сказать. при замкнутой линии 485 прочитанное не равно отправленному, прочитанного вообще нет. Да и проверку делали - 1 бит в пакете специально били..... во время передачи пакета в линию слали байт с др конца линии..... Защита отлично работает.


Цитировать
Идеальное решение для борьбы с коллизиями - выжидать паузу тишины в линии перед отправкой
так и делается. перед отправкой жду тишину, тока потом передача с контролем. А если без контроля, то где гарантия, что одновременно 2 ( или 32) устройства выждав паузу не начнут передавать одновременно?
Записан
Bepec
Гость
« Ответ #8 : Январь 23, 2013, 11:37 »

Это и есть протокол, чётко описанный. В котором описано взаимодействие устройств друг с другом.
Стандартный - Master-Slave. Один опрашивает, остальные только отвечают.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.183 секунд. Запросов: 22.