voytalexey
Гость
|
|
« : 29-09-2008 16:23 » |
|
Здравствуйте! Как можно синхронизировать время внутри USB-микроконтроллера с системным таймером в операционной системе? Делаю собственный USB-device на базе AT89C5131. Драйвер для него пишу тоже сам. Какие есть способы согласования измерения времени внутри девайса и Windows? Например, девайс с периодом 1 мс сканирует состояние портов, складывает в массив, затем шлёт это в драйвер. Как драйвер (или даже конечное приложение) может соотнести время конкретного скана внутри микроконтроллера с внутренним системным временем? Одна из частей девайса это просто набор кнопок, и нужно знать время их нажатия и отпускания. Какие могут быть способы, и какова их точность? Спасибо, надеюсь на ваши соображения.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #1 : 29-09-2008 17:08 » |
|
посмотрите формат пакета... помоему там разбито все на кадры. и быть может получится по номеру кадра восстановить. хотя насчет точности - большой вопрос... а какая нужна?
да и то... кто гарантирует, что пакет от устройства передастся в текекущем кадре? только написание собственного контроллера USB... но тут есть моменты: не уврен что кадры синхронизированы с часами машины) думаю там разные кварцы - будет разбегаться понемногу.
если тупо в лоб делать - можно по приходу пакета в драйвекре опрашивать часы... если пакеты на DPC хотя бы обрабатываются - есть шанс уложится в 1мс... но вообще надо понимать - гарантий никаких)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
voytalexey
Гость
|
|
« Ответ #2 : 01-10-2008 09:02 » |
|
Спасибо за готовность помочь. Точность нужна не хуже одного тика системного таймера Windows.
Была мысль, чтоб написать функцию согласования таймеров так: приложение измеряет системное время Widows, запоминает, отправляет в МК запрос вида "выдать текущее состояние внутреннего таймера МК", МК отвечает, приложение получает ответ, и в этот момент снова измеряет системное время Widows. Если предположить, что длительность выполнения запроса "туда" и "обратно" одинаковое, то можно вычислить, какое время было внутри Windows в тот момент когда МК начал отрабатывать запрос. Но никаких гарантий того, что длительность запроса "туда" и "обратно" одинаковое, нет. И ещё я подумал, может есть уже готовые методы согласования счетчиков времени внутри USB-девайсов и Windows? Способ через написание собственной функции мне кажется кривоватым.
Немного не понял замечание "если пакеты на DPC хотя бы обрабатываются - есть шанс уложится в 1мс..." Если я в драйвере засекаю системное время в момент прихода пакета, какая разница, в синхронном или асинхронном режиме я обрабатываю пакет?
Огромное спасибо за помощь.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #3 : 01-10-2008 12:08 » |
|
APIC 3МГц? 330нс?! нереально. винда и вообще архитектура x86 на это не расчината "впринципе".
по замечанию - нет гарантии того, что момент обработки пакета совпадает со временем его прихода. может пройти до 10(в ЛУЧШЕМ случае) а то и сотен мкс.
можно попробовать измерять относительное время, по номеру цикла шины USB. помоему там было такое понятие. посмотрите в Агурове арбитраж шины и поля пакетов.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
voytalexey
Гость
|
|
« Ответ #4 : 03-10-2008 10:49 » |
|
Здравствуйте. Что-то я совсем перестал понимать замечания. Кто такой APIC? И почему он 3МГц? И как это относится к проблеме согласования систем измерения времени в Windows и МК?
То, что WinXP это не система реального времени, это понятно. Потому и хотел узнать, с какой точностью можно согласовывать времена. И вот что получилось после некоторых мучений. В драйвере моего устройства попробовал засекать системное время перед отправкой пакета URB в драйвер шины и системное время при возврате. Использовал функцию KeQueryPerformanceCounter(). Получилось, что запрос типа BULK IN размером 8 байт (ровно в максимальный размер пакета конечной точки) обрабатывался за 1.30+-0,05 мс. В драйвере отправка данного пакета происходит в обработчике DeviceIOControl. Пробовал измерять время из exe-шника, перед вызовом DeviceIOControl и после него, использовал функцию QueryPerformanceFrequency. Получил время 1.91+-0,05 мс. При тестировании на данной шине было только моё устройство, рядом никто не мешался, и шина была свободна. Так что в принципе нашелся способ согласования времени в Windows и МК с точностью 2 мс. Для моей текущей задачи величина вполне приемлемая. Но неприятный осадок остался. Ведь хост-контроллер периодически посылает в шину SOF-пакеты, в них содержится номер кадра, который мог бы использовать мой USB-девайс. И драйвер хост-контроллера вполне может знать, как соотносится номер кадра с системным временем. Только вот я не нашел способа, как эту информацию достать (если она вообще имеется). Так что приходится пользоваться обходными путями. Огромное спасибо за помощь.
|
|
|
Записан
|
|
|
|
|
voytalexey
Гость
|
|
« Ответ #6 : 18-10-2008 08:12 » |
|
Спасибо за наводку. Действительно, таки есть возможность соотнести номера кадров с системным временем используя QueryBusTime() и USB_BUS_INTERFACE_USBDI_V0. К тому же в NuMega DriverStudio есть функция KUSBLowerDevice::GetCurrentFrameNumber(); Я её как-то незаметил сразу. В общем, в итоге имеется возможность согласовать время в МК и Windows с точностью до одного кадра USB, 1 миллисекунда. Огромное спасибо за помощь.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #7 : 18-10-2008 10:11 » |
|
((( ну не подсаживайтесь же на классы нумеги! умерла она! читайте DDK - это гораздо полезнее! ну сами же себе яму копаете!
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|