Страниц: [1]
  Печать  
Автор Тема: modbus  (Прочитано 4864 раз)
dmrom
Участник
*
Offline Offline

Сообщений: 12


Просмотр профиля
« : Июля 28, 2004, 04:13:47 pm »

Можно несколько вопросов специалистам?
1. Как лучше реализовать функцию чтения из последовательного порта с таймаутом порядка сотен микросекунд? Очень жаль что у readcond() таймаут в десятых секунды измеряется...
2. Как убедиться, что все записанные данные ушли в линию?
Читать регистры UART? А может как-то можно отключить FIFO в UART? Или еще какие-то способы есть?

P.S. qnx 6
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #1 : Июля 28, 2004, 07:16:46 pm »

1. select()
2. tcdrain()
To disable FIFO read usage message
# use devc-ser8250
And restart the driver (but I believe FIFO is disabled by default).
Записан
dmrom
Участник
*
Offline Offline

Сообщений: 12


Просмотр профиля
« Ответ #2 : Июля 29, 2004, 06:53:01 am »

ed1k
1. select()

Ууу, а если работу с modbus отдельным тредом оформлять, да еще с другими дескрипторами нужно работать? select() как-то не очень удобно... А если использовать блокирующий read() и перед ним вызывать ualarm()? Это плохо?
Записан
dmrom
Участник
*
Offline Offline

Сообщений: 12


Просмотр профиля
« Ответ #3 : Июля 29, 2004, 12:56:55 pm »

Еще вопрос. Хочу выставить RTS, выждать таймаут в несколько милисекунд (например 2мс) и сбросить RTS. Пробовал использовать и devctl и ioctl. Реальное время активности RTS (по осциллографу) получается около 20 мс. Это нормально? Что, большую точность получить не удастся?
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #4 : Июля 30, 2004, 06:54:22 am »

dmrom
Ууу, а если работу с modbus отдельным тредом оформлять, да еще с другими дескрипторами нужно работать? select() как-то не очень удобно...

Я не вижу принципиальной разницы, разве что select() требует пару строк больше кода, чем readcond(). Обоим нужен дескриптор. Кроме того, из своего опыта, ну не нужны сотни микросекунд для Modbus. На какой скорости он у вас работает?
dmrom
А если использовать блокирующий read() и перед ним вызывать ualarm()? Это плохо?

После R. Krten я, наверно, второй ярый ненавистник сигналов Чего вы этим добьетесь или что это принципиально улучшит?
dmrom
Пробовал использовать и devctl и ioctl. Реальное время активности RTS (по осциллографу) получается около 20 мс. Это нормально? Что, большую точность получить не удастся?

На какой платформе? Тактовая частота процессора? И еще - как таймаут выжидаете (код, пожалуйста) и с каким приоритетом, и, собственно, 'uname -a'
Записан
dmrom
Участник
*
Offline Offline

Сообщений: 12


Просмотр профиля
« Ответ #5 : Июля 31, 2004, 05:38:57 pm »

ed1k
На какой платформе? Тактовая частота процессора? И еще - как таймаут выжидаете (код, пожалуйста) и с каким приоритетом, и, собственно, 'uname -a'

dmrom-q:~ # uname -a
QNX dmrom-q 6.2.1 2003/01/18-02:12:22est x86pc x86

Приоритеты никакие не устанавливал, а нужно?
Проблемный код вот:

data = _CTL_RTS_CHG | _CTL_RTS;  // set RTS
devctl(FD, DCMD_CHR_SERCTL, &data, sizeof(data), NULL);
data = _CTL_DTR_CHG | 0;         // clear DTR
devctl(FD, DCMD_CHR_SERCTL, &data, sizeof(data), NULL);

usleep(1750);

data = _CTL_RTS_CHG | 0;         // clear RTS
devctl(FD, DCMD_CHR_SERCTL, &data, sizeof(data), NULL);
data = _CTL_DTR_CHG | _CTL_DTR;  // set DTR
devctl(FD, DCMD_CHR_SERCTL, &data, sizeof(data),  NULL);

Вобще-то проблема вот откуда идет...
Физический интерфейс - RS-485 (полудуплекс, как известно).
После передачи пакета мастер (комп с QNX) должен в течение времени, равного длительности передачи 3,5 байт, переключиться на прием, чтобы начать принимать ответ слейва.
Для конфигурации 19200E1 время передачи одного байта равно ~0,5 мс, и 3,5-байтовый интервал равен ~1,8 мс.

Мы используем конвертер RS-232/RS-485, в котором прием/передача переключаются сигналом RTS.

В данный момент проблема в том, что сигнал RTS сбрасывается через 20-50 мс после окончания передачи пакета мастером в линию, а слейв отвечает через 10 мс после окончания пакета мастера. Естественно, ответ слейва до мастера не доходит.
Записан
tol
Участник
*
Offline Offline

Сообщений: 0


Просмотр профиля
« Ответ #6 : Июля 31, 2004, 10:06:28 pm »

Мы для интерфейса RS485 всегда используем преобразователь
RS232/RS485 с автоматическим переключением прием/передача, например ADAM-4520. Поэтому дергать RTS нет необходимости, да и надежность передачи/приема высокая на любых скоростях.
Записан
bob
Участник
*
Offline Offline

Сообщений: 0


Просмотр профиля WWW
« Ответ #7 : Августа 02, 2004, 11:16:22 am »

dmrom
В данный момент проблема в том, что сигнал RTS сбрасывается через 20-50 мс после окончания передачи пакета мастером в линию, а слейв отвечает через 10 мс после окончания пакета мастера. Естественно, ответ слейва до мастера не доходит.

Эта проблема уже обсуждалась. Поищите "rs-485". Насколько помню, программно проблему решить не удалось, только с некоторыми аппаратными "примочками"
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #8 : Августа 02, 2004, 09:06:51 pm »

Физический интерфейс и откуда проблема я знаю. Мы тоже использовали конвертер с переключением направления с помощью RTS. Все работало, правда мы пользовали виндовс, не qnx Собственно, потому как слэйв никогда самостоятельно не инициирует передачу, то и прием с коротким таймаутом не очень нужен (до тех пор пока вы не хотите серьезно нагрузить RS485 и опрашивать устройства как можно чаще). Это к изначальному вопросу С переключением передача/прием проблема серьезней. Приоритет задавать надо, так как usleep() блокируется на таймере, т.е. ваш поток переходит в блокированное состояние. После истечения таймаута, он перейдет в состояние Ready, но это не значит, что он тут же начнет исполняться. Он будет ждать, пока будут обслужены все Ready потоки с более высоким приоритетом. Кроме того, время в 2-5 мс (практика показывает, что такие задержки допустимы) на переключение направления довольно таки жесткое требование. Нужно еще ClockPeriod() выставить где-то 100-200 мкс, т.к. 1 мс по умолчанию не даст вам требуемой временнОй точности системы (при отсутствии потоков с высшим приоритетов, за исключением ядра, конечно, время задержки должно получится 4-8 мс по моим скромным подсчетам). Кроме того, если запущен фотон, то учтите, что некоторые драйвера видеокарт могут существенно деградировать реалтаймовость системы. То же относится к некоторым сетевым картам.
В принципе, слегка подправив devc-ser8250 можно получить требуемый эффект и не трогая time slice системы. При передаче байта ставить RTS, после передачи последнего байта, там где посылается сообщение всем ждущим drain, сбрасывать RTS. Исходники есть в char DDK.
Записан
Страниц: [1]
  Печать  
 
Перейти в: