LINUX.ORG.RU

[C++] /dev/ttyS0 - время отклика

 


0

0

Приветствую всех.

Есть задача реализовать MDB(multi-drop-bus) - что-то вроде RS-485: полудуплекс, сеть устройств с отношением master-slaves, на скорости 9600 baud, формат байта: STRTBIT-DATABITS[0..7]-MODEBIT-STPBIT(бит чётности определяет признак адреса устройства). Самое интересное требование по реализации это время максимального отклика для устройств - 5 mS (Остальные промежутки >100 mS) - оно и вызывает у меня основные затруднения. Запускаться приложение будет сначала на x86 для тестирования, а затем будет портировано на ARM.

Изучив доступную документацию обнаружил, что минимальное время для работы таймеров в Linux определяет значение 1/HZ сек. Для новых x86 этот параметр имеет значение 1000 - т.е минимальное время 1 мс. А вот для ARM это значение равно 100 - т.е минимальное время 10 мс. Встаёт вопрос как обеспечить это время отклика?

Пока что пришёл к таким мыслям: Чтобы реализовать время отклика, я буду ловить прерывания от порта и отсылать ответ о приёме данных. Проблема в том, что надо будет писать модуль для ядра и обеспечивать обмен с остальной частью приложения, которая будет в обычном userspace.

Вопросы:

1) Существуют ли иные способы реализации 5 ms отклика?

2) Как лучше всего организовать обмен между двумя частями приложения: модулем ядра и обычным приложением? (обмен должен быть своевременным).

Тут RTOS нужна будет

anonymous
()

Уууу... Для этого тебе нужна RTOS. Если ядро не preemptive - то ничего у тебя не получится, имх. Можно попробовать настроить таймер на 1кгц. Можно посмотреть на патч рт-линукс (как-то так он назывался). В любом случае, с системным 100гц таймером и непреемптив ядром ты ничего вменяемого не сделаешь...

anonymous
()

> Изучив доступную документацию обнаружил, что минимальное время для работы таймеров в Linux определяет значение 1/HZ сек.

Это не так. Hi-res timers дают точность в микросекунды-десятки микросекунд.

> А вот для ARM это значение равно 100 - т.е минимальное время 10 мс.

Не знаю, как с hi-res для ARM, но наверняка ядро можно пересобрать и с CONFIG_HZ == 1000.

> Чтобы реализовать время отклика, я буду ловить прерывания от порта и отсылать ответ о приёме данных.

Тогда зачем тебе вообще таймер? :) Может, тебе более интересны задержки планирования?

> 1) Существуют ли иные способы реализации 5 ms отклика?

Как минимум, тебе нужно будет включить CONFIG_PREEMPT, а может, и использовать -rt, см. http://rt.wiki.kernel.org Вообще, насколько критичен пропуск директивного срока?

> 2) Как лучше всего организовать обмен между двумя частями приложения: модулем ядра и обычным приложением?

Обычного poll/read/write должно хватить, И я не уверен, что тебе вообще нужен модуль ядра.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

> В любом случае, с системным 100гц таймером и непреемптив ядром ты ничего вменяемого не сделаешь...

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

mv ★★★★★
()
Ответ на: комментарий от mv

Не факт. В том-то и дело :( При сильной загрузке, например, сетью - будет куча прерываний сетевушки, а если ещё и другой ввод-вывод есть - то пропустить можно.

anonymous
()
Ответ на: комментарий от anonymous

> Не факт. В том-то и дело :( При сильной загрузке, например, сетью - будет куча прерываний сетевушки, а если ещё и другой ввод-вывод есть - то пропустить можно.

Если такая большая нагрузка на железо будет, то и железо соответствующее надо. На двухголовой машине, например, обработчик прерываний от активно дёргающейся сетевухи можно на один проц посадить, а свой обработчик компорта - на другой.

mv ★★★★★
()
Ответ на: комментарий от mv

>> Не факт. В том-то и дело :( При сильной загрузке, например, сетью - будет куча прерываний сетевушки, а если ещё и другой ввод-вывод есть - то пропустить можно.

> Если такая большая нагрузка на железо будет, то и железо соответствующее надо.

Аааатставить! Нужно просто назначить приоритеты обработчикам прерываний (ага, это требует -rt ядра).

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Аааатставить! Нужно просто назначить приоритеты обработчикам прерываний (ага, это требует -rt ядра).

Нуууу... :) Отставлять всё равно надо с оглядкой. Дёрганье прерываниями для ядра тоже небесплатно, я лично видел, как (слабая) машина захлёбывается от нагрузки по сети.

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

mv ★★★★★
()

> Тут RTOS нужна будет

Слишком радикальное решение - да и руководство деньги лишние не хочет тратить, потому и переводит на GNU/Linux проект. Вообще пожелание заказчика обойтись стандартными средствами.

>Не знаю, как с hi-res для ARM, но наверняка ядро можно пересобрать и с CONFIG_HZ == 1000.

пока что нельзя пересобирать - см. выше

>Тогда зачем тебе вообще таймер? :) Может, тебе более интересны задержки планирования?

Нужно отслеживать "молчание" устройств - если не пришёл ответ за 5 мс.

>насколько критичен пропуск директивного срока?

Человеческие жизни не пострадают ;) - в принципе при пропуске данные должны передаваться при последующем опросе устройстве(polling). Нужно просто отсылать подтверждение приёма данных(ACK) в течение 5мс после запроса согласно документации и если требуется организовывать последующий обмен данными.

>Обычного poll/read/write должно хватить, И я не уверен, что тебе вообще нужен модуль ядра.

Я тоже не уверен - все остальные требования по времени могут быть реализованы в обычном приложении.

> Не факт. В том-то и дело :( При сильной загрузке, например, сетью - будет куча прерываний сетевушки, а если ещё и другой ввод-вывод есть - то пропустить можно.

Сильной загрузки сетевой скорее всего и не будет. Насколько я понял, моё приложение будет сосуществовать с главным приложением реализующим общую логику работы всей системы и обмениваться с ним изредка информацией посредством сокетов.

necromant ★★
() автор топика
Ответ на: комментарий от necromant

>> Вообще пожелание заказчика обойтись стандартными средствами.

>>Не знаю, как с hi-res для ARM, но наверняка ядро можно пересобрать и с CONFIG_HZ == 1000.

> пока что нельзя пересобирать - см. выше

"Стандартные средства" на ARM? 8) Ты что - делаешь коробочное приложение, которое пользователь будет сам устанавливать на ОС по выбору?

>> Тогда зачем тебе вообще таймер? :) Может, тебе более интересны задержки планирования?

> Нужно отслеживать "молчание" устройств - если не пришёл ответ за 5 мс.

Думаю, точное отслеживание тайм-аута некритично.

tailgunner ★★★★★
()
Ответ на: комментарий от necromant

>> Нужно отслеживать "молчание" устройств - если не пришёл ответ за 5 мс.

Я может конечно чего-то и недопонимаю, но чем не подходит select/*poll? ИМХО 5мс - это не такой уж и маленький промежуток времени и RT-ядро (как и другие специализированные средства) тут не обязательны. В крайнем случае можно своему процессу давать приоритет реального времени (как это сделано например в pulseaudio + см. в сторону модуля http://www.sourceforge.net/projects/realtime-lsm/).

P.S. ИМХО.

Deleted
()
Ответ на: комментарий от Deleted

> Я может конечно чего-то и недопонимаю, но чем не подходит select/*poll? ИМХО 5мс - это не такой уж и маленький промежуток времени

Тайм-ауты обычно отрабатываются с гранулярностью 1/CONFIG_HZ. Если он будет 100, то гранулярность будет 10мс.

tailgunner ★★★★★
()

>формат байта: STRTBIT-DATABITS[0..7]-MODEBIT-STPBIT

Некоторые usart поддерживают 9 бит данных аппаратно - так что можно не изобретать велосипед с битами четности а ожидать адрес в 9 битном режиме и потом переключаться на нормальные 8 бит ( по сути прием 9 битных данных будет означать что пришел адрес устройства) - не надо будет постоянно откликаться на все посылки в интрфейсе, возможно и отклик в 5 мс не потребуется :) Кстати микроконтроллеры на базе арм должны этот режим поддерживать.

>что-то вроде RS-485
>время максимального отклика для устройств - 5 mS

С этим я хз - у меня не было задач где бы на медленных интерфейсах требовалось так быстро реагировать.

koTuk
()
Ответ на: комментарий от Deleted

Советую посмотреть в сторону халявных RTOS с посиксом. На мой взгляд - самое простое и здравое решение :)

Собственно, для этого они и делались

anonymous
()
Ответ на: комментарий от anonymous

RTOS (если речь о RTAI/RTLinux подобных) здесь не подходит. Лучше запихнуть всю "срочную" работу в обработчик прерываний.

rphy
()
Ответ на: комментарий от tailgunner

>"Стандартные средства"

"a standard Linux tty interface to the default kernel UART serial driver"

>Ты что - делаешь коробочное приложение, которое пользователь будет сам устанавливать на ОС по выбору?

Вопрос в последующей поддержке приложения. Да и ARM только в далёком будещем стоит.

>> Изучив доступную документацию обнаружил, что минимальное время для работы таймеров в Linux определяет значение 1/HZ сек.

>Это не так. Hi-res timers дают точность в микросекунды-десятки микросекунд.

>Тайм-ауты обычно отрабатываются с гранулярностью 1/CONFIG_HZ. Если он будет 100, то гранулярность будет 10мс.

Насчёт точности таймеров я взял это из

1) http://www.ddj.com/cpp/184402031?pgno=1

http://www.ddj.com/cpp/184402031?pgno=5

2) Ядро Linux, 3-е изд., Бовет Д., Чезати М. - СПб:БХВ-Петербург, 2007. - 1104 с.: ил. ISBN 978-5-94157-0

на стр.328. - проверка таймеров проводиться функциями отложенного выполнения ;)

Можно конечно вопользоваться функциями задержки - но они нагрузят систему

necromant ★★
() автор топика
Ответ на: комментарий от necromant

> Насчёт точности таймеров я взял это из

> 1) http://www.ddj.com/cpp/184402031?pgno=1

> http://www.ddj.com/cpp/184402031?pgno=5

Что-то не вижу я там таймеров. nanosleep - это не совсем таймер, IIRC, он реализуется как занятое ожидание для RT-процессов.

Впрочем, на первой странице упомянут /dev/rtc - вполне нормальное решение для тайм-аутов (можно добавить nanosleep по вкусу).

tailgunner ★★★★★
()

а если собрать ядро NOHZ? :) Правда, такое не все архитектуры поддерживают.

true_admin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.