Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.06.10;
Скачать: [xml.tar.bz2];

Вниз

Точность измерения временных интервалов для UART в windows   Найти похожие ветки 

 
vertal ©   (2006-12-24 17:20) [0]

По com-порту отправляю сообщение (WriteFile). Жду завершения его отправки через FlushFileBuffers. Пытаюсь принять ответ, состоящий из символов. Признаком конца сообщения-ответа служит отсутствие прибытия  нового символа после предыдущего в течение более 4 милисекунд. Максимальная длина ответа - 256 символов. Осуществляется это все как:

 PurgeComm(fPort, PURGE_RXCLEAR);
 OpResult = WriteFile(fPort, Msg, cnt, &Garbage, NULL);
 FlushFileBuffers(fPort);
 OpResult = ReadFile(fPort, OutBuf, 257, &ActualRead, NULL);

Для того, чтобы после 4 милисекунд отсутствия символов на линнии ReadFile вернула то, что было прочитано, предварительно вызываю SetCommTimeouts, со значением 4 в  ReadIntervalTimeout. Проблема в том, что при таких условиях _иногда_ (через раз примерно) прием сообщения-ответа прекращался на середине. То есть я предполагаю, что это из-за неточности измерения таких промежутков времени windows или стандартными драйверами. После установки ReadIntervalTimeout в значение 16 (8 не помогло) сбои исчезли. Сталкивался ли кто-нибудь с подобным? Или что-то не так в приведенном коде?


 
RayGun ©   (2007-01-02 12:05) [1]

16 мс - квант времени Windows. С помощью SetCommTimeouts установить значение таймаута меньше 16 мс не получиться, Windows может на это время отобрать управление у твоего процесса. Можно попробовать работать с com-портом в асинхронном режиме (overlapped) и использовать CreateWaitableTimer (вроде бы обеспечивает бОльшую точность), WaitForMultipleObjects.


 
Anatoly Podgoretsky ©   (2007-01-02 12:15) [2]

> RayGun  (02.01.2007 12:05:01)  [1]

квантs времени Windows они разные, но только не 16 мс


 
RayGun ©   (2007-01-02 13:16) [3]

> Anatoly Podgoretsky ©   (02.01.07 12:15) [2]

Разные, да, но по умолчанию вроде 10-16 мс, или не так?


 
RayGun ©   (2007-01-02 13:33) [4]

Более-менее приемлемую точность (1-2 мс) может обеспечить multimedia timer (TimeGetDevCaps, TimeBeginPeriod, TimeSetEvent), но может не работать в версиях   Windows ниже NT4.0


 
tesseract ©   (2007-01-02 13:59) [5]

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


 
vertal ©   (2007-01-02 15:09) [6]

Системные часы тикают с интервалом в 10 мс.
Но по моим представлениям, отсчет временных интервалов для символов с UART должен осуществляться на более низком уровне, чем thread sheduling, и величина этого кванта и переключение потоков не должны влиять на его точность. Мне не нужен именно таймер высокой точности, мне нужно чтобы система определяла времена прихода символов по UART с точностью едеиницы мс. В справке нет никаких комментариев по поводу точности выдерживания параметров из _COMMTIMEOUTS, которые задаются в мс. Смотрели на осциллографе - в самом приходящем сообщении нет таких пауз. Такое поведение наблюдается на двух системах - 2000 и XP.


 
С   (2007-01-02 15:46) [7]

Исходя из симптомов можно предположить следующее:

Во время интервала ожидания некий сторонний поток запросил процессорное время и, естественно получил его в размере 10 МСек. После этого управление вернулось Вашему потоку. Так как с момента вызова ReadFile времени прошло больше, чем было Вами установлено в качестве таймаута, то произошел возврат из функции по таймауту. Видимо, система проверяет таймаут до того, как проверит состояние буфера приема UART. Можно рассуждать, логично ли делать так, но вряд ли это имеет смысл. Я, например, считаю, что так поступать правильно, кто-то со мной не согласится. Но факт есть факт - разработчики сделали так, а не иначе.

Не обижайтесь, но я считаю неверным сам подход - закладываться на таймаут как признак конца передачи. Таймаут можно использовать как признак выхода устройства из строя, установив его разумным, но никак не признак окончания передачи. Наилучшим на мой взгляд вариантом будет переделка протокола. Можно, например, передавать размер пакета или определить символ-признак конца. Это будет стандартным, апробированным и надежным решением. Если это почему-либо не подходит, то выхода видится два - собственный драйвер UART или, что предпочтительнее, буферное устройство, которое будет "приводить" протокол обмена к нормальному для Windows виду.


 
vertal ©   (2007-01-03 00:01) [8]

> С   (02.01.07 15:46) [7]</a>
Похоже, что дело обстоит так, как вы описали. Я считаю, что раз в справке по WinAPI пишут, что интервалы задаются в мс, то и делали бы разработчики Windows стандартный драйвер, способный всегда, а не через раз корректно обрабатывать такие параметры.
Не обижайтесь, но я считаю неверным сам подход - закладываться на таймаут как признак конца передачи.
Устройство должно реализовывать некий стандартный протокол (ModBus/RTU), где как раз idle line в течение (4 мс) служит признаком конца сообщения, я не могу этот протокол менять.
то выхода видится два - собственный драйвер UART или, что предпочтительнее, буферное устройство
Написание драйвера я за примемлемое время не потяну, остановился просто на варианте с увеличенными таймаутами. Что мне не нравится - если ReadFile действительно проверяет эти таймауты по предположенному алгоритму, то даже их увеличение не гарантирует от такого рода ошибок - если система очень занята например.


 
Германн ©   (2007-01-03 02:40) [9]


> то выхода видится два - собственный драйвер UART или, что
> предпочтительнее, буферное устройство

Готов обсудить! Гарантирую, моё буферное устройство, твои запросы полностью удовлетворит!


 
RayGun ©   (2007-01-03 09:58) [10]

> С   (02.01.07 15:46) [7]
> Не обижайтесь, но я считаю неверным сам подход - закладываться на таймаут как признак конца передачи.

Подход, конечно, не годится для не real-time OS, но используется в некоторых промышленных стандартах на протоколы обмена (например, ModBus RTU, где между пакетами выдерживаются паузы продолжительностью 3,5 от времени передачи одного байта). Чтобы такие протоколы работали под Windows, разработчики, как правило, увеличивают таймауты до значений, кратных кванту Windows (что, конечно, криво и неправильно, но работает). Как я понял, в данном случае протокол обмена построен по принципу Master/Slave: компутер (Master) посылает запрос, а подключаемое устройство (Slave) должно ответить на него не более чем через 4 мс. Если не очень критично, то почему бы просто не установить таймаут побольше (например, 20 мс)?


 
С   (2007-01-03 10:20) [11]

>vertal ©

А как у Вас установлены остальные члены COMMTIMEOUTS?


 
RayGun ©   (2007-01-03 10:41) [12]

> vertal ©   (03.01.07 00:01) [8]
> Что мне не нравится - если ReadFile действительно проверяет эти таймауты по предположенному алгоритму, то даже их увеличение не гарантирует от такого рода ошибок - если система очень занята например.

Чтобы минимизировать такого рода ошибки, можно поднять приоритет процессу или потоку до TimeCritical, тогда больше вероятности, что ваше приложение получит свой квант времени и прочитает данные, принятые драйвером, даже при большой загрузке системы.


 
kaZaNoVa ©   (2007-01-03 10:51) [13]

 
Var k, h:int64;
QueryPerformanceFrequency(h);
QueryPerformanceCounter(k);


 
RayGun ©   (2007-01-03 10:59) [14]

> kaZaNoVa ©   (03.01.07 10:51) [13]

Измерять интервалы будет точно, но делу поможет только в том случае, если ReadFile будет использоваться в асинхронном режиме, т.е. сразу после вызова возвращать управление, не зависимо от того, приняты данные или нет. Тогда таймаут можно организовать в цикле, вызывая ReadFile и QueryPerformanceCounter, и проверяя, пришли ли данные или истек таймаут, но такой поток будет "кушать" процессорное время, причем довольно сильно. И опять же, ничего не мешает Windows отобрать у потока в середине данного цикла процессорное время на те же 10 мс.


 
kaZaNoVa ©   (2007-01-03 11:19) [15]

RayGun ©   (03.01.07 10:59) [14]
Тогда таймаут можно организовать в цикле, вызывая ReadFile и QueryPerformanceCounter, и проверяя, пришли ли данные или истек таймаут, но такой поток будет "кушать" процессорное время, причем довольно сильно. И опять же, ничего не мешает Windows отобрать у потока в середине данного цикла процессорное время на те же 10 мс.


контролировать можно в отдельном потоке с критическим приоритетом и sleep(1) для снятия нагрузки на систему)


 
RayGun ©   (2007-01-03 11:31) [16]

> kaZaNoVa ©   (03.01.07 11:19) [15]

Да, наверное, так будет проще, чем с мультимедийным таймером и событиями


 
Anatoly Podgoretsky ©   (2007-01-03 15:34) [17]

> RayGun  (03.01.2007 11:31:16)  [16]

Только REAL TIME OS, подходят ДОС и однозадачные микроконтроллеры.


 
vertal ©   (2007-01-03 19:57) [18]


> Германн ©   (03.01.07 02:40) [9]
> Готов обсудить! Гарантирую, моё буферное устройство, твои
> запросы полностью удовлетворит!

Да я верю. Мы и сами можем такое сделать. Вопрос в целесообразности. Эта программа для PC, которую я сейчас пишу, будет тестовой программой, позволяющей проверять работоспособность наших контроллеров. Поставлять вместе с ней еще какое-то дополнительное устройство - будет слишком жирно.
RayGun ©   (03.01.07 09:58) [10]
Как я понял, в данном случае протокол обмена построен по принципу Master/Slave: компутер (Master) посылает запрос, а подключаемое устройство (Slave) должно ответить на него не более чем через 4 мс.
Да, Master-Slave, да сейчас компьютер выспутает в роли мастера. Подключаемое устройство должно ответить за некий разумный интервал (сейчас поставлено 80 мс), а idle line > 4 мс - (при baud rate 9600 бит/с это и есть 3,5 символа) это признак конца сообщения.
Если не очень критично, то почему бы просто не установить таймаут побольше (например, 20 мс)?
Да можно. Так видимо и останется. Прсто хочется понять причину такого поведения системы.

> С   (03.01.07 10:20) [11]
> >vertal ©А как у Вас установлены остальные члены COMMTIMEOUTS?
>

Вопрос конечно по теме. Сейчас
ReadIntervalTimeout = 4 (работает через раз) или 16 (работает всегда)
ReadTotalTimeoutMultiplier = 0
ReadTotalTimeoutConstant = 80
Для приведенного кода еще критично, чтобы FlushFileBuffers возвращала управление только после того, как буфер действительно будет очищен. Судя по описанию, она так и должна поступать.

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

Я пробовал повышать приоритет потока, работающего с портом. Не заметил разницы в частоте возникновения сбоев.


Anatoly Podgoretsky ©   (03.01.07 15:34) [17]
Только REAL TIME OS, подходят ДОС и однозадачные микроконтроллеры.

Видимо да.


 
С   (2007-01-03 21:19) [19]

>vertal ©   (03.01.07 19:57) [18]

Попробуйте так:
ReadIntervalTimeout = 4
ReadTotalTimeoutMultiplier = 0
ReadTotalTimeoutConstant = 0

Моожет статься, это даст дополнительную пищу для размышлений.


 
tesseract ©   (2007-01-03 21:27) [20]


> kaZaNoVa ©   (03.01.07 11:19) [15]
> RayGun ©   (03.01.07 10:59) [14] Тогда таймаут можно организовать
> в цикле, вызывая ReadFile и QueryPerformanceCounter, и проверяя,
>  пришли ли данные или истек таймаут, но такой поток будет
> "кушать" процессорное время, причем довольно сильно. И опять
> же, ничего не мешает Windows отобрать у потока в середине
> данного цикла процессорное время на те же 10 мс.контролировать
> можно в отдельном потоке с критическим приоритетом и sleep(1)
> для снятия нагрузки на систему)


Проще написать драйвер. Так 16 мс не выловишь.


 
kaZaNoVa ©   (2007-01-03 21:32) [21]

tesseract ©   (03.01.07 21:27) [20]
даже при критическом приоритете как процесаа так и потока?


 
tesseract ©   (2007-01-03 21:34) [22]


> kaZaNoVa ©   (03.01.07 21:32) [21]


Соломон тебя прибьёт.

Новогоднее предложение !!!!! Выставь любому процессу TIME_CRITICAL и получи BSOD!!!!


 
kaZaNoVa ©   (2007-01-03 21:36) [23]

tesseract ©   (03.01.07 21:34) [22]
Выставь любому процессу TIME_CRITICAL и получи BSOD!!!!

шутка? в винде у мну всегда работало)

про линукс не знаю


 
tesseract ©   (2007-01-03 21:39) [24]


> шутка? в винде у мну всегда работало)


Зависит от загрузки проца. В нормальных микроядерных/RTOS нет такого параметра.

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


 
Германн ©   (2007-01-04 01:22) [25]


> vertal ©   (03.01.07 19:57) [18]
>
>
> > Германн ©   (03.01.07 02:40) [9]
> > Готов обсудить! Гарантирую, моё буферное устройство, твои
> > запросы полностью удовлетворит!
>
> Да я верю. Мы и сами можем такое сделать. Вопрос в целесообразности.
>  Эта программа для PC, которую я сейчас пишу, будет тестовой
> программой, позволяющей проверять работоспособность наших
> контроллеров. Поставлять вместе с ней еще какое-то дополнительное
> устройство - будет слишком жирно.

Не понял???
Проверка работоспособности, имхо, обязанность ОТК производителя!


> Признаком конца сообщения-ответа служит отсутствие прибытия
>  нового символа после предыдущего в течение более 4 милисекунд.
>  Максимальная длина ответа - 256 символов.

Может тогда сменить идеологию? И сделать так, как делают многие. В первом байте ответа посылать длину вышеназванного. И при приёме её контролировать?


 
tesseract ©   (2007-01-04 09:22) [26]


> Может тогда сменить идеологию? И сделать так, как делают
> многие. В первом байте ответа посылать длину вышеназванного.
>  И при приёме её контролировать?

А почему бы CTS/RTS не использовать? Стандартный механизм RS232C?

Обычно для контроля хватает и просто посылки, длину из знакомых устройств никто не посылал. И время ожидания не -4 мс, а 200 мс.  Окончание посылки можно и байтом посылать, и CRC для точночти добавить.


 
Германн ©   (2007-01-04 14:08) [27]


> А почему бы CTS/RTS не использовать? Стандартный механизм
> RS232C?
Так это лишние провода :(
>
> Обычно для контроля хватает и просто посылки, длину из знакомых
> устройств никто не посылал. И время ожидания не -4 мс, а
> 200 мс.  Окончание посылки можно и байтом посылать, и CRC
> для точночти добавить.

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


 
tesseract ©   (2007-01-04 15:07) [28]


> Так это лишние провода :(


Зато надёжно!.


 
RayGun ©   (2007-01-04 16:03) [29]

> tesseract ©   (04.01.07 09:22) [26]

> А почему бы CTS/RTS не использовать? Стандартный механизм RS232C?

> Обычно для контроля хватает и просто посылки, длину из знакомых устройств
> никто не посылал. И время ожидания не -4 мс, а 200 мс.  Окончание посылки
> можно и байтом посылать, и CRC для точночти добавить.

CRC16 является частью протокола ModBus RTU, используемого автором темы.
По стандарту передача ведется в полудуплексном режиме, в случае RS-485 это два-три провода (DATA+, DATA- и IGND по желанию), в случае RS-232 - три провода (Rx, Tx, GND).
Как уже говорил автор, протокол переделывать нельзя.
Остается вопрос - либо превращать Windows в некоторое подобие REAL TIME OS (такое в общем-то возможно, если переписать нужную часть HAL:), либо иметь гемор с потоками TimeCritical и "высокоточными" средствами измерения времени, либо просто увеличить таймаут, как в основном делают АСУшники:)

Что касается вопроса автора темы, уважаемого vertal ©  "Просто хочется понять причину такого поведения системы", так на этот вопрос уже ответили уважаемые С (02.01.07 15:46) [7] и Anatoly Podgoretsky © (03.01.07 15:34) [17]


 
vertal ©   (2007-01-05 00:01) [30]


> С   (03.01.07 21:19) [19]

Пробовал, ни на что значение ReadTotalTimeoutConstant не влияет, дело не в ней.
Не понял???Проверка работоспособности, имхо, обязанность ОТК производителя!
Понятно, что все модули после изготовления (если еще дойдет до серийного производства) будут проверяться. А с помощью этой утилитки можно будет проверить модуль в любой момент, сконфигурировать его через удобный интерфейс, и просто наглядно увидеть выполняемые им функции и возможные настройки. Подобную утилитку распространяет Advantech для своих промышленных контроллеров ADAM-4000-5000.
RayGun ©   (04.01.07 16:03) [29]
Хоть кто-то меня слушает. Протокол жестко задан. Линия связи в ModBus - всего два провода, перед компьютером стоит конвертер RS-485<->RS-232, CTS и RTS не используются.

Остановлюсь действительно на варианте с увеличенным таймаутом. Специально привел в вопросе фрагмент кода - но с самим кодом видимо действительно все в порядке, раз до сих пор никто в нем не увидел ошибок. Для меня несколько неожиданно было обнаружить такую я бы сказал недоработку в Windows.


 
kaZaNoVa ©   (2007-01-05 00:06) [31]

Удалено модератором
Примечание: Offtopic


 
Германн ©   (2007-01-05 01:55) [32]


> Хоть кто-то меня слушает. Протокол жестко задан. Линия связи
> в ModBus - всего два провода, перед компьютером стоит конвертер
> RS-485<->RS-232, CTS и RTS не используются.

Да не внимательно читал, увы. Кстати, имхо, "идиотский" протокол этот ModBus. Хорошо, что мы о нём не слыхали, когда разрабатывали свои первые устройства. Нормальная работа по такому протоколу возможна только в рамках, которые привёл АП в [17].


 
Anatoly Podgoretsky ©   (2007-01-05 10:08) [33]

vertal ©   (05.01.07 00:01) [30]
О какой ошибки ты говоришь?


 
RayGun ©   (2007-01-05 10:10) [34]

> Германн ©   (05.01.07 01:55) [32]

> Кстати, имхо, "идиотский" протокол этот ModBus. Хорошо, что мы о нём не
> слыхали, когда разрабатывали свои первые устройства. Нормальная работа по
> такому протоколу возможна только в рамках, которые привёл АП в [17].

Да, Ваше мнение склонны разделять практически все, кто имел удовольствие работать с этим "замечательным" протоколом под Windows и Linux. К сожалению, это стандарт, и многие девайсы его используют.


 
RayGun ©   (2007-01-05 10:12) [35]

> Anatoly Podgoretsky ©   (05.01.07 10:08) [33]

> О какой ошибки ты говоришь?

Видимо, о том, что Windows не REAL TIME OS


 
Anatoly Podgoretsky ©   (2007-01-05 13:37) [36]

> RayGun  (05.01.2007 10:12:35)  [35]

Вообще то REAL TIME OS, но они разные эти REAL TIME OS бывают. Для данной задачи данная вариант не подходит, как минимум нужна Windows XX Embeded, а лучше ДОС, более жесткой системы реального времени нет.


 
tesseract ©   (2007-01-05 15:51) [37]


>  как минимум нужна Windows XX Embeded,


Да это та же винда, только тебе дают лицензию, что ты лично можешь порезать как захочешь.  Типа nanoBSD. И вроде своп по умолчанию вырублен.

ЗЫ: Ну почему я все приглашения на семинары МS embedded выкидывал в урну?


 
RayGun ©   (2007-01-05 19:11) [38]

Есть вроде бы неплохая REAL TIME OS жесткого реального времени, которая в определенной степени поддерживает WinAPI - называется RTOS-32, под нее некоторые люди даже на Delphi пишут, в силу личных симпатий и предпочтений. Но стОит денег, для утилит настройки/конфигурирования/тестирования не годится, больше подходит в качестве альтернативы Windows XX Embedded, QNX, Windows CE для АСУшных задач, а также для любых других серьезных задач, где требуется жесткий real-time.


 
tesseract ©   (2007-01-05 19:13) [39]


>  Windows CE


На RTOS слабо тянет.


 
RayGun ©   (2007-01-05 19:25) [40]

> tesseract ©   (05.01.07 19:13) [39]

>  Windows CE

> На RTOS слабо тянет.

Да, слабо тянет, были в свое время по этому поводу большие споры, вроде бы ее отнесли к системам мягкого реального времени.



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.06.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 3.219 c
2-1179571724
LoRd1
2007-05-19 14:48
2007.06.10
Как убить задачу, зная только имя .exe


15-1179253032
N3xt_
2007-05-15 22:17
2007.06.10
Программа


3-1174498152
olevacho_
2007-03-21 20:29
2007.06.10
Определение пользователя и компьютера


9-1153207029
Lam3r
2006-07-18 11:17
2007.06.10
DirectX обучение


15-1179109412
Slider007
2007-05-14 06:23
2007.06.10
С днем рождения ! 14 мая





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский