Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как перехватить аппаратное прерывание в USB?  (Прочитано 9409 раз)
0 Пользователей и 1 Гость смотрят эту тему.
jur
Помогающий

lt
Offline Offline

« : 06-02-2008 09:01 » 

Привет!

Сразу прошу прощения за, возможно, примитивное мышление: я пока не умею писать драйверы. Поэтому хочу для начала попросить знающих людей помочь.

А вопрос у меня такой. Имеется устройство на шине USB 2.0, разработанное с применением микросхемы CY7C68013A фирмы Cypress. Устройство выдает пакеты данных размером 512 байт (передача производится через Bulk endpoint). Для приема данных в компьютер используется драйвер CyUSB.sys этой же фирмы. На компьютере установлена Win XP.

Возникла необходимость предварительно сортировать получаемые пакеты сразу после их прибытия, т.е. прямо в драйвере. Этого нельзя сделать запрашивая драйвер CyUSB.sys из приложения (т.е. принимать по одному пакету и потом сортировать), т.к. серьезно страдает производительность. Предполагаю, что это происходит из-за переключений User <-> Kernel. Поэтому приходится запрашивать сразу по 16 пакетов, а сортировку производить потом (в приложении).

Фирма Cypress также дает другой свой драйвер в виде исходных текстов (ezusbsys.c), взяв за основу который можно разработать собственный драйвер, обеспечивающий требуемую функциональность.

Этот драйвер (как, наверное, и любой другой драйвер устройства на USB) обращается с запросами к драйверу нижнего уровня USBD.

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

Скажите, пожалуйста, а нельзя-ли как-то "вклиниться" в эту аппаратную обработку прерывания? Т.е. сказать драйверу нижнего уровня, что, мол, "вызови ка ты вот эту мою функцию, когда получишь пакет данных". Или для моей функциональности достаточно просто обращаться к драйверу нижнего уровня за каждым пакетом в отдельности? Это не вызовет потерь производительности? (Ведь в конце концов драйвер USBD получает пакеты из USB все-равно по одному.)

Спасибо!
Записан

MPEG-4 - в массы!
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 06-02-2008 10:54 » 

это называется драйвер-фильтр.
ставится между двумя драйверами (например драйвером шины и драйвером функционального устройства) и фильтрует все пакеты.
честно говоря сам такие никогда не писал...так что навскидку не подскажу.
а вообще если у вас есть исходный код Сайпресовского драйвера - логичнее будет переделать прям его. впрочем вопрос насколько он различается с тем, что вы уже используете.
если там кроме Bulk режима ничего не надо - может имеет смысл написать свой драйвер?)

PS а к аппаратномоу прерыванию подключатася не надо) это совершенно лишнее) да и гемороя больше.
PPS да, правда не уверен что фильтр тут поможет... зависит от интерфейса.
в общем я бы наверное переписал свой драйвер.... Bulk - это просто. а вот с чем OHCI кушать - это я не знаю...наверянка он там используется?
если нет - однозначно свой драйвер)
« Последнее редактирование: 06-02-2008 10:59 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
jur
Помогающий

lt
Offline Offline

« Ответ #2 : 06-02-2008 12:46 » 

это называется драйвер-фильтр.
ставится между двумя драйверами (например драйвером шины и драйвером функционального устройства) и фильтрует все пакеты.
честно говоря сам такие никогда не писал...так что навскидку не подскажу.
а вообще если у вас есть исходный код Сайпресовского драйвера - логичнее будет переделать прям его. впрочем вопрос насколько он различается с тем, что вы уже используете.
если там кроме Bulk режима ничего не надо - может имеет смысл написать свой драйвер?)

Я использую CyUSB.sys от Cypress. Это коммерческий драйвер, но позволяется использовать его бесплатно при условии применения их же микросхемы. Однако, исходного текста этого драйвера нет.

А режим работы у нас только Bulk.

PS а к аппаратномоу прерыванию подключатася не надо) это совершенно лишнее) да и гемороя больше.

Да, я тоже подумал, что это "штука коническая" (С) :-) Только мне пока непонятно, как построить алгоритм работы своего драйвера...

PPS да, правда не уверен что фильтр тут поможет... зависит от интерфейса.
в общем я бы наверное переписал свой драйвер.... Bulk - это просто. а вот с чем OHCI кушать - это я не знаю...наверянка он там используется?
если нет - однозначно свой драйвер)

Наверное стоит кроме исходников драйвера ezusbsys.c посмотреть еще и примеры из DDK, верно?

В принципе мне представляется, что мой драйвер должен работать примерно так:

1. При запуске приложения драйвер инициализируется и запускает внутренний поток на считывание входных пакетов (с помощью PsCreateSystemThread). Для хранения поступающих данных заводятся два буфера (мне нужно сортировать входящие пакеты на две группы). Буфера - двойные: один заполняется, другой отдается приложению.

2. Поток постоянно клянчит у нижестоящего драйвера очередной пакет. Поток просматривает каждый полученный пакет и помещает его в один из двух буферов хранения (т.е. входные пакеты сортируются по двум группам).

3. Когда в одной или другой группе накапливается необходимое число пакетов, поток вырабатывает Event, уведомляющий приложение о готовности входных данных. При этом драйвер переключается на накопление следующего буфера, пока приложение будет читать заполненный.

4. Приложение получает один из Event'ов и читает требуемые данные обычной командой чтения данных.

5. По завершению приложения все ресурсы освобождаются.

Я правильно понимаю примерный порядок действий? Ведь с помощью потока считывания я смогу избежать использования аппаратных прерываний?
Записан

MPEG-4 - в массы!
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 07-02-2008 08:48 » 

да, в целом все так.
1. двойные буфера или непрерывные - это вам решать, например для потоковых вводов данных я использую один кольцевой буфер.
2. да. смотрите UsbBuildInterruptOrBulkTransferRequest оно же _URB_BULK_OR_INTERRUPT_TRANSFER
3. именно. только смотрите чтоб приложение/драйвер не запутались что-кто читает)
4. кстати, сигнализацию можно сделать иначе. приложение посылает запрос чтения (ReadFile - например или DeviceIoControl) драйвер его ставит в очередь, а завершает, только тогда, когда сформирован целый пакет. но в принципе - суть та же. кстати в этом случае можно обойтись и без потока в драйвере... поток будет формироваться очередью запросов от приложения. но это только пример, что больше вам подойдет, смотрите сами.

Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
jur
Помогающий

lt
Offline Offline

« Ответ #4 : 07-02-2008 16:50 » 

да, в целом все так.

Большое спасибо за разъяснение! Снова поштудирую литературу и попробую приступить к этому делу.
Записан

MPEG-4 - в массы!
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines