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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QtSerialPort и rs485 без автоматического RTS  (Прочитано 4818 раз)
titan83
Гость
« : Август 25, 2014, 11:18 »

Всем привет.
Знаю, что такая тема уже поднималась, но есть у меня есть специфика(
В общем, в моем устройстве на ARM9 rs485 реализован на чипах ADMxxx без автоопределения RTS, а в качестве RTS выступает просто линия GPIO, которую надо прижать к земле перед передачей и отпустить после, соответственно, setRequestToSend для меня неактуально.
Выставить RTS перед посылкой нетрудно - трудно ее вовремя снять. Я пробовал вариант с сигналом bytesWritten(qint64), но он поступает когда данные будут переданы в системную функцию write(), и при этом число переданных байт будет всегда равно отправляемому. В результате из 10 байт я успеваю послать 4.
В качестве второго варианта я хотел использовать функцию waitForBytesWritten(), но она, видимо, не переопределена в QSerialPort и всегда возвращает false.
И похоже, что мне придется активно читать форумы по переделке драйверов uart, чтобы выставлять в какой-нибудь файл sysfs "0" в момент окончания передачи.
Может все-таки возможно решить эту задачу высокоуровневыми средствами?
Спасибо.
Записан
Bepec
Гость
« Ответ #1 : Август 25, 2014, 13:23 »

Да, руки надо отрывать тем, кто их разрабатывает без авто RTS Улыбающийся

Windows система НЕ реального времени. Поэтому точно и быстро реализовать "прижимание" линии не получится. Всегда будет погрешность ~ 50 мс, что очень плохо скажется на скорости и частоте передач.

update: ммм.. ты на встроенной системе программу пишешь? Или на какой?
« Последнее редактирование: Август 25, 2014, 19:22 от Bepec » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Август 25, 2014, 22:31 »

Цитировать
Я пробовал вариант с сигналом bytesWritten(qint64), но он поступает когда данные будут переданы в системную функцию write(), и при этом число переданных байт будет всегда равно отправляемому.

Не. Планировалось так, чтобы сигнал bytesWritten() излучался именно тогда, когда данные "были отправлены" в устройство. Т.е. когда сработала аналогия select() && fdwrite (QSocketNotifier с типом Write), т.е. когда передающий буфер драйвера вновь готов к заполнению новыми данными для передачи. Да, это понятно, что реально это не означает, что если передающий буфер опустел то данные переданы в линию. В реальности все сложнее.. Но тем не менее "косвенно" можно примерно на это положиться.

Еще ты можешь попробовать использовать QSerialPort::handle() для вызова сисколла ioctl() с флагом FIONWRITE чтобы посмотреть сколько там данных в буфере драйвера еще готовы к отправке но еще не отправились и как-то поллить это. Но этот FIONWRITE поддерживается не всеми драйверами и ядрами (вроде как), да и вообще не факт что заработает.

UPD: Или можешь также попробовать использовать этот самый QSerialPort::handle() и через ioctl() установить порт в блокирующий режим (т.к. по-умолчанию он открывается в неблокирующем). Тогда уж точно функция write() будет ждать пока данные не отправятся. Но в этом случае тебе придется перенести QSerialPort в отдельный поток, т.к. сам понимаешь - блокирующий ввод/вывод - это блокирующий ввод/вывод.  Улыбающийся

Цитировать
В качестве второго варианта я хотел использовать функцию waitForBytesWritten(), но она, видимо, не переопределена в QSerialPort и всегда возвращает false.

Да не, вроде она должна работать. Если не работает - значит какой-то касяк в QSerialPort .
« Последнее редактирование: Август 25, 2014, 22:38 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
titan83
Гость
« Ответ #3 : Август 27, 2014, 08:15 »

Да, руки надо отрывать тем, кто их разрабатывает без авто RTS Улыбающийся
Так не получается найти микросхему, чтобы и автоRTS и оптроны на выходе(( У ADM - оптроны, у MAX - автоRTS((, а чтобы и то, и другое - не получается пока найти. А ставить еще и оптроны - так места на плате не хватит однозначно.
update: ммм.. ты на встроенной системе программу пишешь? Или на какой?
У меня на ARM9 крутиться линукс 3.2.18
Записан
titan83
Гость
« Ответ #4 : Август 27, 2014, 08:17 »

Спасибо, буду пробовать, но чувствую, что это все полумеры и придется-таки падать на уровень ядра и задействовать один из свободных таймеров( а так не хочется)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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