Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Согласование времени в USB-device и Windows
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
Алексей__
Здравствуйте!
Делаю собственный USB-device на базе AT89C5131.
Драйвер для него пишу тоже сам.
Какие есть способы согласования измерения времени внутри девайса и Windows?
Например, девайс с периодом 1 мс сканирует состояние портов,
складывает в массив, затем шлёт это в драйвер.
Как драйвер (или даже конечное приложение) может соотнести время конкретного скана внутри микроконтроллера с внутренним системным временем?
Одна из частей девайса это просто набор кнопок,
и нужно знать время их нажатия и отпускания.
Какие могут быть способы, и какова их точность?
Спасибо, надеюсь на ваши соображения.
MrYuran
как вариант - передавать на ПК состояние кнопок и таймштамп, например, внутренний счётчик тиков.
То есть в ПК фиксируется время нажатия и отжатия. Соответственно, вычисляется задержка.
Если я правильно понял проблему.
Алексей__
Спасибо за готовность помочь.
Но мне не нужно согласование разных событий внутри контроллера
(типа нажатие и отпускание кнопок).
Нужно согласование событий внутри контроллера и времени внутри Windows.
У меня есть доступ к тикам системного таймера Widows (функция GetTickCount).
Внутри контроллера тоже есть стетчик времени.
А как их увязать друг с другом?
Вот это непонятно.
Была мысль, чтоб написать функцию согласования таймеров так:
приложение измеряет системное время Widows, запоминает, отправляет в МК запрос вида "выдать текущее состояние внутреннего таймера МК", МК отвечает, приложение получает ответ, и в этот момент снова измеряет системное время Widows.
Если предположить, что длительность выполнения запроса "туда" и "обратно" одинаковое, то можно вычислить, какое время было внутри Windows в тот момент когда МК начал отрабатывать запрос.
Но никаких гарантий того, что длительность запроса "туда" и "обратно" одинаковое, нет.
И ещё я подумал, может есть уже готовые методы согласования счетчиков времени внутри USB-девайсов и Windows?
Спсоб через написание собственной функции мне кажется кривоватым.
Спасибо за помощь.
MrYuran
А исходная -то задача какая?
ВременнАя синхронизация в винде, да ещё с учётом задержек драйверов и т.д. - задача малоперспективная. Хотя, для интереса, можно попробовать передать что-то в контроллер, тут же отправить обратно и посчитать задержку. Не удивлюсь, если задержка будет порядка десятков миллисекунд, причём ненормируемая
koyodza
Цитата(Алексей__ @ Oct 1 2008, 11:50) *
У меня есть доступ к тикам системного таймера Widows (функция GetTickCount).
Внутри контроллера тоже есть стетчик времени.
А как их увязать друг с другом?
Вот это непонятно.

Вообще-то GetTickCount хоть и показывает время в мсек от запуска Windows, на самом деле имеет дискретность (шаг приращения) не 1мсек, а значительно больше: от 16-17 мсек для ХР до 55мсек для 98/МЕ. Вас устроит такая дискретность?
В виндовс есть и другие функции для работы с мелкими временными интервалами - GetPerfomanceCounter, например, но их использование чуть более сложное wink.gif


Цитата(Алексей__ @ Oct 1 2008, 11:50) *
Была мысль, чтоб написать функцию согласования таймеров так:
приложение измеряет системное время Widows, запоминает, отправляет в МК запрос вида "выдать текущее состояние внутреннего таймера МК", МК отвечает, приложение получает ответ, и в этот момент снова измеряет системное время Widows.
Если предположить, что длительность выполнения запроса "туда" и "обратно" одинаковое, то можно вычислить, какое время было внутри Windows в тот момент когда МК начал отрабатывать запрос.
Но никаких гарантий того, что длительность запроса "туда" и "обратно" одинаковое, нет.

Все правильно, никаких гарантий одинаковости этого времени нет. Но обычно это и не нужно. Да и зачем? Обычно достаточно учета времени в самом девайсе
Алексей__
Исходная задача: психологическое тестирование людей с использованием компьютера и включенного в него внешнего устройства. На экране чего-то происходит, человек жмёт кнопки на устройстве. Соответственно, нужно знать, когда что произошло на экране, и с какой задержкой человек на это отреагировал. Вот и встала задача согласования измерения времени в Windows и МК. В принципе, погрешность 10-20 мс заказчика пока что устраивает.
Цитата
Вообще-то GetTickCount хоть и показывает время в мсек от запуска Windows, на самом деле имеет дискретность (шаг приращения) не 1мсек, а значительно больше: от 16-17 мсек для ХР до 55мсек для 98/МЕ.

Позволю себе маленькое замечание:
как ни странно, в Win98 дискретность GetTickCount составляет 2-3мс.
Хотя системный таймер действительно генерирует прерывания с периодом около 55 мс.
Вот такая была историческая странность.
В семействе WinNT вроде дискретность GetTickCount действительно совпадает периодом прерываний.

И спасибо за наводку на PerfomanceCounter.

Теперь собственно о заявленной теме.
В драйвере моего устройства попробовал засекать системное время перед отправкой пакета URB в драйвер шины и системное время при возврате. Использовал функцию KeQueryPerformanceCounter(). Получилось, что запрос типа BULK IN размером 8 байт (ровно в максимальный размер пакета конечной точки) обрабатывался за 1.30+-0,05 мс.
В драйвере отправка данного пакета происходит в обработчике DeviceIOControl.
Пробовал измерять время из exe-шника, перед вызовом DeviceIOControl и после него, использовал функцию QueryPerformanceFrequency. Получил время 1.91+-0,05 мс.
При тестировании на данной шине было только моё устройство, рядом никто не мешался, и шина была свободна.
Так что в принципе нашелся способ согласования времени в Windows и МК с точностью 2 мс. Для моей текущей задачи величина вполне приемлемая.
Но неприятный осадок остался. Ведь хост-контроллер периодически посылает в шину SOF-пакеты, в них содержится номер кадра, который мог бы использовать мой USB-девайс. И драйвер хост-контроллера вполне может знать, как соотносится номер кадра с системным временем. Только вот я не нашел способа, как эту информацию достать (если она вообще имеется). Так что приходится пользоваться обходными путями.
Огромное спасибо всем, кто мне помогал.
MrYuran
Пришла в голову такая идея.
По событию в РС (вспышка на экране или что там у вас...) отправляется запрос на контроллер.
Контроллер тут же выдаёт обратно текущее время. А по реакции "пациента" (кнопка или что там...) контроллер опять выдаёт текущее время.
По-моему, так можно точнее задержку вычислить.

Только вот не понятно: а почему нельзя клавиатуру самого компа использовать? Тогда вообще не надо было бы ничего отправлять и ловить
Алексей__
За идею спасибо.
А стандартную клавиатуру пробовали, но она не подходит.
Тестирование должно быть на рабочем месте, или недалеко от него.
И к тому же мобильным -> используется ноутбук.
А у многих испытуемых пальцы шире чем размер клавиш (машинисты поездов и т.д.).
Так что нажимают сразу по несколько клавиш.
Или ещё хуже, случайно попадают на дурацкие клавиши "Windows" или "Меню".
Соответственно, вылетают из программы.
Да и неравные условия тестирования получаются для людей знакомых с компьютером и незнакомых с ним. А отдельный выносной пульт всех уравнивает в шансах.
К тому же всё равно USB устройство подразумевается (ритмокардиограф). Так что просто добавится к нему функциональности.
Ещё раз спасибо.
koyodza
Цитата(Алексей__ @ Oct 3 2008, 18:58) *
Да и неравные условия тестирования получаются для людей знакомых с компьютером и незнакомых с ним. А отдельный выносной пульт всех уравнивает в шансах.

Делал когда-то для медиков-учёных подобную фигню - прибор для измерения времени реакции (там, правда, еще и температура несколькими датчиками измерялась). Ключевой момент - ПК не участвует в процессе, только отображает результат и передает на дальнейшую обработку. Возбуждающий сигнал (звук/свет - 2 цвета) формируется самим прибором. Советую и Вам пойти таким путем.
Алексей__
В моём случае ПК очень даже участвует в процессе (и графика, и звук).
Так что за совет спасибо, а пойду всё-же своим путём.
К тому же я был неправ, всё-таки есть официальная возможность соотнести номер USB-кадра и системное время Windows.
Подсказали добрые люди на forum.shelek.ru
Есть DDK-шные функция QueryBusTime() и структура USB_BUS_INTERFACE_USBDI_V0.
А в NuMega DriverStudio есть функция KUSBLowerDevice::GetCurrentFrameNumber()
Так что имеется возможность надёжно согласовать время в МК и Windows с точностью до одного кадра USB, 1 миллисекунда.
Огромное спасибо за помощь.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.