Будет ли перемещение кода в пространство ядра давать более точную синхронизацию? - PullRequest
7 голосов
/ 25 декабря 2011

Справочная информация:

В настоящее время у меня есть аппаратное устройство, которое подключается к USB-порту. Аппаратное устройство отвечает за отправку точных периодических сообщений в различные сети, к которым оно, в свою очередь, также подключается. Внутри аппаратного устройства у меня есть пара микрочипов dsPIC. Есть два режима работы.

Один сценарий - это отправка простых «заданий» в dsPIC, которые, в свою очередь, могут отправлять точные сообщения с точностью до 0,001 мс. Эта архитектура не идеальна для более сложных сообщений, когда нам необходимо отправлять периодический пакет, который изменяется в зависимости от событий, происходящих в приложении для ПК. Таким образом, у нас есть второй режим работы, когда наше приложение для ПК будет отправлять периодические сообщения, а dsPIC просто конвертируют и передают в ответ. Все это, между прочим, прозрачно для конечного пользователя нашего программного обеспечения. Наше аппаратное устройство - это испытательный инструмент, используемый в автомобильной отрасли.

В настоящее время мы используем USB-последовательный чип от FTDI и драйверы FTDI для Windows, чтобы связать оборудование с нашим программным обеспечением для ПК.

Проблема в том, что во втором режиме, когда мы отправляем сообщения с ПК, лучшее, что мы можем достичь - это около 1 мс в среднем аппаратном диапазоне. Мы подвергаемся упреждению ядра Windows. Я попробовал несколько «хитростей» для улучшения таких вещей, как:

  1. Убедиться в том, что наши потоки читателей и писателей живут, когда это возможно, на отдельных процессорах.
  2. Увеличение приоритета потока писателя при уменьшении приоритета читателя.
  3. Информирование пользователя об отключении экранной заставки и других приложений при использовании нашего программного обеспечения.
  4. Замена вызовов createthread вызовами CreateTimerQueueTimer.

Все наше программное обеспечение написано на C / C ++. Я очень хорошо знаком с продвинутым программированием Windows; такие как IO Completions, Overlapped I / O, очереди потоков без блокировки (на самом деле стратегия проектирования), сокеты, потоки, семафоры и т. д. *

Однако я ничего не знаю о разработке драйверов для Windows. Я прочитал несколько статей о KMDF против UDMF против WDM.

Я надеюсь, что опытный разработчик драйвера режима ядра Windows ответит здесь ...

Следующая версия На нашем оборудовании есть возможность заменить чип FTDI и использовать либо интерфейс USB dsPIC, либо, возможно, перенести материал FTDI с открытым исходным кодом Linux на Windows и продолжить использовать чип FTDI в нашем специальном драйвере. Я думаю, что, перейдя к драйверу режима ядра на стороне ПК, я могу установить драйвер ядра, который может отправлять периодические сообщения с более точными интервалами без прерывания и / или, возможно, используя преимущества DMA.

У нас есть конкурент в нашем бизнесе, который, я думаю, делает то же самое с их инструментами. Насколько я знаю, приложения пользовательского пространства не могут планировать поток лучше, чем 1 мс. В настоящее время мы используем timeGetTime в потоке. Я экспериментировал с таймерными очередями (через CreateTimerQueueTimer) без реального улучшения.

Является ли WDM правильным подходом для достижения более точной синхронизации?

Наш конкурент кое-как добивается очень точной синхронизации от сигналов, управляемых Windows, до их аппаратного обеспечения, и они загружают драйвер ядра (.sys), а их устройство работает по USB2.0, как и наше.

Если WDM - это путь, могу ли я посоветовать, какие функции ядра мне следует изучить для настройки времени? Спасибо за чтение

Ответы [ 3 ]

5 голосов
/ 24 января 2012

В режиме ядра вы можете позволить себе запуск DPC с кратностью 100-наносекундных интервалов без прерываний.DPC не может быть прерван (он же прерывается планировщиком потоков), потому что планировщик потоков также является DPC.Прерывание все еще может выгрузить DPC.Таким образом, значение интервала 10 должно помочь вам сделать обратный вызов с предельной точностью.

Однако у вас нет доступа ко многим функциям, таким как память с подкачкой или пространство памяти определенного потока на уровне DPC.потому что они работают в произвольном контексте.Может быть полезно отложить обработку до контекста вашего собственного пользовательского режима, используя APC, который имеет доступ к дополнительным функциям.

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

Еще одно замечание о поведении вытеснения Windows: Менеджер набора баланса временно повышает приоритет потока, когда поток сигнализируется асинхронным событием (щелчок графического интерфейса пользователя,запуск по таймеру, завершение ввода / вывода), чтобы позволить коду завершения завершать свою обработку с меньшим приоритетом.Использование обработчика асинхронного таймера должно дать достаточный импульс для предотвращения вытеснения хотя бы для кванта.Интересно, почему ваш код не попадает в это окно?Однако, похоже, что вы не единственные, у кого есть проблемы с точностью таймера: http://www.virtualdub.org/blog/pivot/entry.php?id=272

Я согласен с Полом в сложности разработки драйверов, но если у вас есть веские основания, это не ракетанаука, просто больше усилий.

1 голос
/ 17 февраля 2013

Ваше внимание к драйверам и производительности ядра скучает по лесу за деревьями.Слон в комнате - факт, что полноскоростные кадры шины USB 2 происходят с периодом 1 мс.Высокоскоростные микрокадры USB 2 выполняются каждые 1/8 мс.

Когда вы отправляете данные через полноскоростной USB (как для большинства чипов FTDI), лучшее, на что может надеяться ваше приложение, - это то, что данные попадут вустройство иногда в течение следующего кадра .С ненагруженной шиной USB передача будет происходить очень близко к началу кадра.Вы будете наблюдать это как гранулярность 1 мс с небольшим случайным отклонением.Это именно то, что вы видите, и это не плохо.Например, поскольку все USB-устройства, подключенные к одному хосту, будут видеть кадры в одно и то же время, это простой способ синхронизации нескольких часов с точностью до микросекунды.Ваше приложение может просто отправить сообщение, в котором есть не только данные, но и некоторое время в ближайшем будущем, когда оно должно быть отправлено.Другая проблема с USB заключается в том, что нет никаких гарантий относительно того, когда будут обрабатываться ваши запросы на передачу данных.В конце концов, вы делите шину с другими устройствами.

Я думаю, что вам нужно перестроить свою систему и не зависеть от какой-либо синхронизации со стороны ПК.Предполагается, что приложение, работающее на ПК, по времени ограничено производительностью человека, который взаимодействует с ним.Все, что требует гарантированной производительности в реальном времени, должно быть на ваших устройствах dsPIC.Даже USB-шина его не обрезает, так как у вас нет никаких гарантий относительно того, как скоро ваш запрос будет намечен на шину.

По сути, если вам требуется гарантированная производительность в режиме реального времени в Windows, тогдане должен быть задействован какой-либо пользовательский режим - он должен all работать в режиме ядра, и вы должны использовать каналы связи, предназначенные исключительно для вас (или вы заставляете их действовать таким образом, например, фильтруя прямо сверхуUSB-хост).

1 голос
/ 27 декабря 2011

Это один из фундаментальных аспектов проектирования ядра Windows - этот код, работающий на пассивном уровне (=> весь код пользовательского режима), подвергается воздействию DPC и прерывается, занимая время, и если вам нужна точность 1us, вы ' вероятно, он не получится ни с UMDF, ни с драйвером пользовательского режима.

Тем не менее, написание драйвера ядра не является легким или дешевым занятием, это очень сложно, даже написать и гарантировать, что он работает на компьютерах ваших клиентов ( много * Требуется 1006 * испытаний). Правильное решение обойдется вам в значительные инженерные ресурсы.

В качестве временного интервала я бы посмотрел в MMCSS для> = Vista (http://msdn.microsoft.com/en-us/library/windows/desktop/ms684247(v=vs.85).aspx), это может дать вам достаточный приоритет, чтобы вы могли быть удовлетворены.

Если вы действительно хотите спуститься в кроличью нору, вам следует использовать KMDF. KMDF - это фреймворк на основе WDM, представляющий множество кодифицированных рекомендаций для водителей. Если вы не обязаны это делать, KMDF - это всегда лучший способ для водителей. И, честно говоря, вы почти наверняка захотите заключить контракт с OSR (http://www.osr.com)) или нанять кого-нибудь (несколько человек?), Имеющих опыт написания драйверов для Windows.

...