Требуется: написать драйвер для устройства, подключающееся к ком-порту, для приема пакетов с разделением времени (т.е. пакеты разделяются не стоп и старт битами, а по временным промежуткам) Временной промежуток при скорости в 9600 примерно равен 0.003 сек.
Вопрос: могут ли таймеры виндовс такое выдержать? Возможно ли написать такой драйвер?
Здравствуйте, kvser, Вы писали:
K>Требуется: написать драйвер для устройства, подключающееся к ком-порту, для приема пакетов с разделением времени (т.е. пакеты разделяются не стоп и старт битами, а по временным промежуткам) Временной промежуток при скорости в 9600 примерно равен 0.003 сек. K>Вопрос: могут ли таймеры виндовс такое выдержать? Возможно ли написать такой драйвер?
1. Стандратный СОМ порт это не GPIO — с него нельзя считывать информацию о текущем сигнале на пине. СОМ порт — это устройство на системной плате и работает оно соглано RS232 — т.е со старт и стоп битами. И по-другому никак. Тут не причем система.
2. 3 мс — это нормально для таймеров ядра. С другой стороны, ядро не является системой реального времени. И поэтому никто не обеспечит точного срабатывания. На точность срабатывания будет влиять: наличие устройств с программным обменом данными ( PIO, особенно это актуально для дисков ), наличие в системе устройств с большой полосой пропускания ( гигабитный эзернет, платы видеозахвата), наличие специализированного ПО работающее в режиме ядра ( например, антивирусы, фаерволы ). На "пустой" машине 3 мс будет выдерживаться весьма точно и погрешность будет в районе единиц мкс.
Здравствуйте, TarasCo, Вы писали:
TC>Здравствуйте, kvser, Вы писали:
K>>Требуется: написать драйвер для устройства, подключающееся к ком-порту, для приема пакетов с
TC>2. 3 мс — это нормально для таймеров ядра.
Мне кажется, что при реализации описанного драйвера система будет жутко тормозить.
Разубедите.
Здравствуйте, TarasCo, Вы писали:
TC>1. Стандратный СОМ порт это не GPIO — с него нельзя считывать информацию о текущем сигнале на пине. СОМ порт — это устройство на системной плате и работает оно соглано RS232 — т.е со старт и стоп битами. И по-другому никак. Тут не причем система.
Нет, это не так.
Сигнал line-break прекрасно управляется. Программными средствами можно организовать любой протокол. При этом, если входяший break будет иметь значение, важно установить максимальную скорость и минимальную длину символа (чтобы break-condition быстрее распозновался UART-ом).
TC>2. 3 мс — это нормально для таймеров ядра. С другой стороны, ядро не является системой реального времени. И поэтому никто не обеспечит точного срабатывания. На точность срабатывания будет влиять: наличие устройств с программным обменом данными ( PIO, особенно это актуально для дисков ), наличие в системе устройств с большой полосой пропускания ( гигабитный эзернет, платы видеозахвата), наличие специализированного ПО работающее в режиме ядра ( например, антивирусы, фаерволы ). На "пустой" машине 3 мс будет выдерживаться весьма точно и погрешность будет в районе единиц мкс.
Нет, это не так.
Все таймеры в NT/W2K/XP призязаны к "тиками" системного времени, по умолчанию это 10-15 мс (зависит от системы), но можно уменьшить до 1 мс. Ядро NT/W2K/XP, при правильном использовании, работает как хорошая real-time система. С учетом приоритетов процессов и т.д. Нарушается это правило в двух случаях:
— когда некачественно написанные драйверы долго выполняют какой-то код на IRQL > DISPATCH_LEVEL;
— когда "как-бы real-time" прикладное ПО написано не правильно, т.е. использует в своей real-time части те системные сервисы, которые по определению not-a-real-time (например файл подкачки).
Здравствуйте, kvser, Вы писали:
K>Требуется: написать драйвер для устройства, подключающееся к ком-порту, для приема пакетов с разделением времени (т.е. пакеты разделяются не стоп и старт битами, а по временным промежуткам) Временной промежуток при скорости в 9600 примерно равен 0.003 сек. K>Вопрос: могут ли таймеры виндовс такое выдержать? Возможно ли написать такой драйвер?
Да, таймеры смогут такое выдержать, но необходимо увеличить частоту системных тиков до 1000 в сек. См. описание ExSetTimerResolution() в Windows DDK.
Да, такой драйвер можно написать и на современных CPU (порядка 1 ГГц) вы "на глаз" не заметите замедление системы из-за частых прерываний.
Но можно обойтись без написания драйвера:
1) Повысить приоритет потоков и процесса до realtime (только после того как отладите);
2) Перейти на overlapped ввод-вывод, см. документацию Platform SDK;
3) Использовать break-condition для приёмо-передачи. При этом важно установить максимальную скорость COM-порта (115200 — не предел, см. http://leo.yuriev.ru/139) и минимальную длину "родного" символа.
4) Как вариант использовать нестандартную схему подключения сигналов к COM-порту. Вести приём-передачу через модемные сигналы, а передачу средствами UART-а использовать для организации "тиков" времени.
Здравствуйте, h0rnet, Вы писали:
TC>>2. 3 мс — это нормально для таймеров ядра.
H>Мне кажется, что при реализации описанного драйвера система будет жутко тормозить.
У меня драйвер позволяет установить частоту таймера до 1000/сек, и в DPC делает обработку посложнее приема/передачи пакетов. На мало-мальски приличной системе (Celeron-400) совершенно не заметна разница между 100 и 1000 прерыванями в секунду.
Здравствуйте, Leo Yuriev, Вы писали:
LY>Сигнал line-break прекрасно управляется. Программными средствами можно организовать любой протокол.
И как предлагаете принимать такие сообщения иначе, чем поллингом состояния UART? С помощью системных таймеров получить требуемую точность можно лишь для очень низких скоростей.
LY>Ядро NT/W2K/XP, при правильном использовании, работает как хорошая real-time система. С учетом приоритетов процессов и т.д. Нарушается это правило в двух случаях: LY>- когда некачественно написанные драйверы долго выполняют какой-то код на IRQL > DISPATCH_LEVEL;
Почему именно ">"? Если чья-то DPC долго выполняется на DISPATCH_LEVEL — Ваша DPC управления не получит. И в средней системе с частотой процессора порядка 2 ГГц опоздания таймерной DPC на 1-2 мс — совершенно нормальное явление.
Здравствуйте, Leo Yuriev, Вы писали:
K>>приема пакетов с разделением времени (т.е. пакеты разделяются не стоп и старт битами, а по временным промежуткам) Временной промежуток при скорости в 9600 примерно равен 0.003 сек.
LY>Да, таймеры смогут такое выдержать, но необходимо увеличить частоту системных тиков до 1000 в сек.
И каким же образом увеличение разрешение таймера до 1 мс поможет принимать битовые (не содержащие стартовых/стоповых битов) пакеты? Период следования бита при 9600 бит/с — 104 мкс.
ЕМ>И каким же образом увеличение разрешение таймера до 1 мс поможет принимать битовые (не содержащие стартовых/стоповых битов) пакеты? Период следования бита при 9600 бит/с — 104 мкс.
Конечно только полингом. 1 мс — только для пауз между "посылками". Самый разумный вариант — использовать CD/DTR для приёма/передачи, а нативный uart-tx только для тиков по 104 us (или сколько потребуется).
Надежность работы такого "софтверного" решения будет конечно не очень (сильно зависит от других драйверов в системе), но "на попробовать" сгодится.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>И как предлагаете принимать такие сообщения иначе, чем поллингом состояния UART? С помощью системных таймеров получить требуемую точность можно лишь для очень низких скоростей.
Имелось в виду, что это в принципе возможно. Либо полингом, либо использовать tx-ready прерывания.
ЕМ>Почему именно ">"? Если чья-то DPC долго выполняется на DISPATCH_LEVEL — Ваша DPC управления не получит. И в средней системе с частотой процессора порядка 2 ГГц опоздания таймерной DPC на 1-2 мс — совершенно нормальное явление.
Имелась в виду работающая при этом обработка прерываний. В данном случае большего не нужно.
Для всех обсуждающих хочу более понятнее описать задачу:
устройства, подключаемые к PC, работают по протоколу MODBUS http://www.contravt.ru/?id=2923, два сообщения разделяются интервалом тишины равного времени передачи 3.5 символов() при данной скорости передачи в сети. Нужно написать ПО под NT/2K/XP, которое рпвильно обрабатывает эти данные.
И можно пожалуйста побольше ссылок(если возможно) на доки.
Здравствуйте, Leo Yuriev, Вы писали:
ЕМ>>И как предлагаете принимать такие сообщения иначе, чем поллингом состояния UART? С помощью системных таймеров получить требуемую точность можно лишь для очень низких скоростей.
LY>Имелось в виду, что это в принципе возможно. Либо полингом, либо использовать tx-ready прерывания.
"В принципе" — это "на сферическом компьютере в вакууме" Допустим, имеем скорость 2400 бит/с — это 0.42 мс/бит. Сколько бит в пакете Вы возьметесь принять без сбоев, учитывая, что пакет может иметь длинные серии единиц или нулей, и в течение такой серии сигналы на входах порта меняться не будут?
Здравствуйте, kvser, Вы писали:
K>Для всех обсуждающих хочу более понятнее описать задачу:
Имело смысл сделать это сразу, чтобы народ не обсуждал невесть что.
K>устройства, подключаемые к PC, работают по протоколу MODBUS http://www.contravt.ru/?id=2923, два сообщения разделяются интервалом тишины равного времени передачи 3.5 символов()
Зачем Вы тогда в первом сообщении стали говорить про стартовые/стоповые биты? Судя по приведенному описанию, пакеты у Вас — байтовые, а не битовые, и байты совершенно стандартно разделяются стоповыми битами. От Вас требуется лишь обеспечить отслеживание таймаута.
Проще всего это сделать, обнаруживая не конец, а начало пакета. То есть, при приеме очередного байта сравнивать время его прихода со временем прихода предыдущего байта (время определять по какому-нибудь таймеру высокого разрешения). Если интервал большой — значит, начался новый пакет. А для того, чтобы отловить конец последнего пакета (при длительной паузе) — заводить таймер на сколько-то миллисекунд в начале каждого пакета.
K>И можно пожалуйста побольше ссылок(если возможно) на доки.
Ссылка в этой области одна — DDK Там есть вся необходимая документация.
K>Требуется: написать драйвер для устройства, подключающееся к ком-порту, для приема пакетов с разделением времени (т.е. пакеты разделяются не стоп и старт битами, а по временным промежуткам) Временной промежуток при скорости в 9600 примерно равен 0.003 сек. K>Вопрос: могут ли таймеры виндовс такое выдержать? Возможно ли написать такой драйвер?
Нет, не могут. Такой дизайн вообще несовместим с железом сериального порта. Используйте старт-стоп биты или байты.
ЕМ>И как предлагаете принимать такие сообщения иначе, чем поллингом состояния UART? С
Никак. Именно потому я и предлагаю потратить больше ментальных усилий на дизайн самого протокола, чтобы не оставаться на уровне сляпанных на коленке ДОС-модемов Lexand образца 1991 года.
K>устройства, подключаемые к PC, работают по протоколу MODBUS http://www.contravt.ru/?id=2923, два сообщения разделяются интервалом тишины равного времени передачи 3.5 символов() при данной скорости передачи в сети. Нужно
Я так понимаю, слово "равного" надо читать "не меньше, чем". Т.е. тишина в 4 символа — это тоже разделитель.
В любом случае я бы сосредоточился на включении извратных режимов в сериальном порту. Надеятся на то, что это можно сделать в софте под виндами — я бы не стал.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[5]: Обработка пакетов с разделением времени
От:
Аноним
Дата:
12.04.06 07:40
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Я так понимаю, слово "равного" надо читать "не меньше, чем". Т.е. тишина в 4 символа — это тоже разделитель.
да, надо читать "меньше чем"
MSS>В любом случае я бы сосредоточился на включении извратных режимов в сериальном порту. Надеятся на то, что это можно сделать в софте под виндами — я бы не стал.