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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Обработка прерываний  (Прочитано 27586 раз)
0 Пользователей и 1 Гость смотрят эту тему.
anatolich
Гость
« : 26-04-2007 07:27 » 

Я реализую следующую схему
В приложении создаю событие и поток где его буду ждать
В драйвере по имени получаю событие
>HANDLE hEvent=NULL;
>PKEVENT KSharEvent=NULL;
>UNICODE_STRING EvName;
>KSharEvent = IoCreateNotificationEvent(&EvName, &hEvent);
Теперь по прерыванию в DPC хочу вызвать KeSetEvent
Как правильно в DPC передать указатель? Через DEVICE_EXTENSION моего DeviceObject?
Или заводить глобальные переменные? Или... ?
Записан
Vlaor
Гость
« Ответ #1 : 26-04-2007 08:14 » 

Я все это дело храню в DEVICE_EXTENSION. Может конечно зто и неправильно.
Записан
Ochkarik
Модератор

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

« Ответ #2 : 27-04-2007 09:15 » 

использую обратную схему. событие создаю в приложении, и передаю драйверу.
в драйвере получаю указатель:
Код:
PKEVENT pkEvent;            //Указатель на Event (поле
status =
    ObReferenceObjectByHandle(  (HANDLE)hEvent, //от приложения
            EVENT_MODIFY_STATE,
            *ExEventObjectType,
            KernelMode,
            (PVOID*)&pkEvent,
            NULL);

из драйвера выставляется на уровне не ниже DPC:
Код:
KeSetEvent(pkEvent,IO_NO_INCREMENT,FALSE);//только FALSE, иначе я должен находится на IQRL==PASSIVE_LEVEL


плюсы такого подхода: при получении ссылки на открытый в ring3 объект - счетчик ссылок на него увеличивается и объект не удалится пока в драйвере не будет вызван
ObDereferenceObject(pkEvent);
и еще не обязательно событие именовать))

но в любом случае хранить вы KEVENT должны в любом NonPagedPool. DEVICE_EXTENSION для этого тоже подходит.

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


PPS как передавать чтото в DPC
объявляете в devExt
Код:
    KDPC  DpcForIsr;      //структура DPC для обработчика ISR
инициализируете:
Код:
    KeInitializeDpc( &devExt->DpcForIsr,&DpcForIsr,devExt->DeviceObject);
используете:
Код:
    KeInsertQueueDpc( &devExt->DpcForIsr,
devExt, <-ваш контекст
NULL);
обрабатываете:
Код:
VOID
DpcForIsr(  IN PKDPC Dpc,
    IN PDEVICE_OBJECT devObj, //==PVOID DeferredContext,
    IN PDEVICE_EXTENSION_MY devExt,
    IN PVOID SysArg2)
{
SOFT_ICE_DEBUG1;
// по идее это все на Dispatch_IRQL выполняется.


    //получаем указатель на device (пригодится так как
    //devExt = DeviceObject->devExt;
   
   
/*    if (devExt->pkEvent)
    {
KeSetEvent(devExt->pkEvent,IO_NO_INCREMENT,FALSE);//только FALSE, иначе я должен находится на IQRL==PASSIVE_LEVEL
    };*/
    KdPrint(("DPCForISR Exit>>>>>>>>>>>>>\n"));
    return;
};

удаляете:
Код:
    KeRemoveQueueDpc(&devExt->DpcForIsr);
« Последнее редактирование: 30-09-2008 18:23 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
anatolich
Гость
« Ответ #3 : 27-04-2007 11:06 » 

Cnacuбо. Соmpuware мне так все и написала. Подправил только DevExt и как вы сказали, так и делаю. Думаю сейчас как лучше определить, что это моя железка выставила прерывание. Нужно смотреть регистр на PCI контроллере. Где это лучше делать - в Isr и в Dpc не лезть или в DpcForIsr.
Записан
Ochkarik
Модератор

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

« Ответ #4 : 28-04-2007 07:50 » 

только в isr. по результатам проверки вы должны вернуть из isr либо true либо false. это необходимо для того чтобы диспечер прерываний винды не продолжал вызывать чужие isr зарегестрированные на том же прерывании. в ддк про обработчик isr все сказано.
dpc нужен для того чтобы event выставлять. потому, что его НЕЛЬЗЯ выставлять на уровне выше DISPATCH_LEVEL , а isr вызывается на уровне DIRQL.
раздел:
Kernel-Mode Driver Architecture: Windows DDK
-> Managing Hardware Priorities
« Последнее редактирование: 28-04-2007 07:57 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
anatolich
Гость
« Ответ #5 : 02-05-2007 06:48 » 

Cnacuбо Ochkarik
Вот нашел ресурс
http://www.codeproject.com/system/driveguicomm.asp?df=100&forumid=3527&exp=0&select=1217398
Записан
Ochkarik
Модератор

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

« Ответ #6 : 02-05-2007 09:28 » 

угу, все так)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
anatolich
Гость
« Ответ #7 : 03-05-2007 10:28 » 

Заработало в такой связке:
в приложении
SomeEvent = CreateEvent(NULL, true, false, "SomeEvent");
DeviceIoControl(DevHandle, IOCTL_XXX,&SomeEvent,sizeof(HANDLE),Null, 0, &L, NULL))

в драйвере
hEvent = *((PHANDLE) inpBuff = Irp->AssociatedIrp.SystemBuffer);
status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL,NULL,KernelMode,&KSharEvent,NULL);

Ну и там уже на DPC
KeSetEvent(deviceExtension->SharEvent, IO_NO_INCREMENT, FALSE);
KeResetEvent(deviceExtension->SharEvent);

А вот где мне посмотреть, что по этому прерыванию именно моя карточка просигналила? Что, я должен смотреть регистры контроллера PCI своей железки, или где нибудь в свойствах
deviceObject ?
Записан
Ochkarik
Модератор

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

« Ответ #8 : 03-05-2007 15:50 » 

я же говорю - в ISR смотрите регистры своей PCI и!!!! аппаратно сбрасываете прерывание если оно ваше (у вас на плате должны быть такая команда!). И!!!! возвращаете true или false в зависимости от того ваше оно или нет.
и вообще была здесь уже такая тема.
поиск - рулит)
остальное - RTFM хоть раз!
Reed The F****** Manual то бишь.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
anatolich
Гость
« Ответ #9 : 04-05-2007 08:44 » 

Ок. У меня контроллер s5920. У него есть регистр (INTCSR). Читая DATA BOOK я понял, что
нужно установить Add-On Interrupt Pin в этом регистре, чтобы плата могла давать прерывания.
Но она ничего не дает. Видеокарта, сидящая на этом же irq сигналит во всю. А как вы пишете
смотреть в ISR, так я смотрю и вижу свой установленный бит и все, но к сожалению не от платы
, а от видеокарты. Это я так просто от расстройства расписался. Понятно что нужно по железке
информацию читать
Записан
Ochkarik
Модератор

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

« Ответ #10 : 04-05-2007 16:40 » new

ну тут уж не знаю, чесно говоря... но там вроде, помимо того что INTCSR установить, еще и само прерывание сгенерировать надо?... вроде бы) да еще сконфигурить кучку регистров...
это я мельком описание глянул)
не могу сейчас долго разбираться, к сожалению...
« Последнее редактирование: 04-05-2007 16:46 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
buisyhanh
Постоялец

vn
Offline Offline

« Ответ #11 : 30-09-2008 16:37 » 

Спасибо всеравно, но вижу в некотором приложении также свзяли по такой схеме и работает, причем PKEVENT тоже использовался.
Если будь интерес смотри:
http://www.codeproject.com/KB/system/driveguicomm.aspx?df=100&forumid=3527&exp=0&select=1217398
Записан
Ochkarik
Модератор

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

« Ответ #12 : 30-09-2008 18:47 » 

эту ссылку уже давали)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sergeyvass
Интересующийся

ru
Offline Offline

« Ответ #13 : 11-08-2016 13:17 » 

Здравствуйте!
У меня похожая ситуация. Имею PCI устройство. Хочу из драйвера, при получении прерывания от устрйоства, активировать событие, которое примет пользовательское приложение. Решил использовать приведённую выше схему.
В приложении создал событие, но при попытке передать его драйверу получаю ошибку (Incorrect function ) от  DeviceIoControl. С чем этом может быть связано? При этом в драйвере я не сделал обработку запросов.

Второй вопрос. Я пишу kmdf драйвер и нашёл несколько статей на эту тему, но для драйверов wdm. Подскажите, пожалуйста, где можно найти аналог для регистрации обработчика событий в kmdf драйвере?
Код:
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = EventSysDeviceControl;
Записан
Ochkarik
Модератор

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

« Ответ #14 : 12-08-2016 15:13 » 


В приложении создал событие, но при попытке передать его драйверу получаю ошибку (Incorrect function ) от  DeviceIoControl. С чем этом может быть связано? При этом в драйвере я не сделал обработку запросов.
- не понял? куда передать? какую обработку?

Второй вопрос. Я пишу kmdf драйвер и нашёл несколько статей на эту тему, но для драйверов wdm. Подскажите, пожалуйста, где можно найти аналог для регистрации обработчика событий в kmdf драйвере?
Код:
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = EventSysDeviceControl;
- каких событий?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sergeyvass
Интересующийся

ru
Offline Offline

« Ответ #15 : 23-08-2016 06:27 » 


В приложении создал событие, но при попытке передать его драйверу получаю ошибку (Incorrect function ) от  DeviceIoControl. С чем этом может быть связано? При этом в драйвере я не сделал обработку запросов.
- не понял? куда передать? какую обработку?

Создаю в приложении новое событие:
Код:
procLaunched.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
Передаю дескриптор на него в драйвер через запрос IOCTL_EVENT_READY:
Код:
result = DeviceIoControl(hDevice, IOCTL_EVENT_READY,
&procLaunched, sizeof(REGISTER_EVENT), NULL,
0, &L, NULL);

Для чего я это делаю? Чтобы драйвер обработал запрос IOCTL_EVENT_READY и получил дескриптор на событие, которое будет ждать приложение. Потом драйвер сможет сделать активным это событие и приложение получит сигнал от драйвера (синхронизация работы драйвера и приложения).

После вызова DeviceIoControl я получаю ошибку Incorrect function. О какой функции идёт речь и что в ней не корректного?
Цитата
Цитата
Цитата: sergeyvass от 11-08-2016 13:17
Второй вопрос. Я пишу kmdf драйвер и нашёл несколько статей на эту тему, но для драйверов wdm. Подскажите, пожалуйста, где можно найти аналог для регистрации обработчика событий в kmdf драйвере?
Код:

 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = EventSysDeviceControl;

- каких событий?
Обработка драйвером вызовов из приложения функции DeviceIoControl.

Записан
Ochkarik
Модератор

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

« Ответ #16 : 24-08-2016 10:29 » 

как определили IOCTL_EVENT_READY
и как обрабатываете?
"&L" - эт что такое? переменная L? вид странный)

Добавлено через 1 минуту и 20 секунд:
то есть событие тут не причем. вы просто структуру не можете передать в драйвер. я правильно понял?
« Последнее редактирование: 24-08-2016 10:31 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sergeyvass
Интересующийся

ru
Offline Offline

« Ответ #17 : 24-08-2016 11:09 » 

Цитата
как определили IOCTL_EVENT_READY
В приложении определил так:
Код:
#define IOCTL_EVENT_READY CTL_CODE(FILE_DEVICE_CONTROLLER, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
Цитата
и как обрабатываете?
В драйвере никак не обрабатываю. В примерах которые нашёл рассматриваются wdm драйвера. В них в driverEntry регистрируется callback:
Код:
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = EventDispatchIoControl;
и уже в нём вызываеется ObReferenceObjectByHandle().
Я же пишу kmdf драйвер и у меня есть структура
Код:
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
. Но не понятно какой callback задействовать для обработки DeviceIoControl().
Значит моя ошибка вызвана тем, что я в драйвере не обрабатываю вызов из приложения DeviceIoControl() ?.
Цитата
"&L" - эт что такое? переменная L? вид странный)
Да это переменная которую я в дальнейшем не буду использовать.
Цитата
то есть событие тут не причем. вы просто структуру не можете передать в драйвер. я правильно понял?
Всё верно.
Записан
Ochkarik
Модератор

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

« Ответ #18 : 24-08-2016 13:15 » 

WDM IRPs and WDF Event Callback Functions
вам нужно обработать
IRP_MJ_DEVICE_CONTROL   == EvtIoDeviceControl or EvtIoDefault

pnpPowerCallbacks- это из другой оперы
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sergeyvass
Интересующийся

ru
Offline Offline

« Ответ #19 : 19-09-2016 12:45 » 

Здравствуйте! Продолжаю писать драйвер для PCI платы. На данном этапе реализована вся требуемая функциональность, однако иногда получаю BSOD ( Ошибка 0хА IRQL_NOT_LESS_OR_EQUAL). Предполагаю, что это связано с неправильным использованием прерываний или обработкой пользовательских запросов.

Вот алгоритм работы моего драйвера:
1) При старте пользовательской программы создаю два события CreateEvent() и передаю дескрипторы на них в драйвер. ( В драйвере делаю активными эти события после прерывания от устройства, а в пользовательской программе жду эти события).
     В обработчике прерываний вызываю
Код:
WdfInterruptQueueDpcForIsr(devExt->Interrupt);
    если прерывание от моего устройства.
    
     В PLxEvtInterruptDpc() делаю активным то, или иное событие
Код:
KeSetEvent(devExt->pkEvent, IO_NO_INCREMENT, FALSE);

    PLxEvtInterruptDpc() и PLxEvtInterruptIsr() вызываются на WdfExecutionLevelDispatch    (на сколько я понимаю). Никаких пользовательских данных, кроме дескрипторов на события здесь не обрабатываю.

2) После получения пользователем события, начинаю вычитывать данные, обращаясь к драйверу.
      Пользовательские запросы на чтение обрабатываю в PLxEvtIoRead(), которое тоже работает на высоком уровне приоритета. Однако тут уже ведётся работа с       пользовательскими буферами ввода-вывода.

Правильно ли я понимаю, что работать с пользовательскими запросами нужно на PASSIVE_LEVEL, потому что иначе пользовательский буфер может быть выгружен из памяти в момент обработки запроса на чтение? Это и приводит к BSOD?
Как понизить уровень приоритета обработчика запросов на чтение?
 

« Последнее редактирование: 19-09-2016 12:55 от sergeyvass » Записан
sergeyvass
Интересующийся

ru
Offline Offline

« Ответ #20 : 22-09-2016 11:04 » 

Сейчас читаю статью о прерываниях и понимаю, что в предыдущем посте написал ерунду. Простите, пожалуйста.
Записан
Ochkarik
Модератор

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

« Ответ #21 : 22-09-2016 11:44 » 

это ничего)
ну тут я полной ерунды не заметил, просто все в одну кучку получилось)
вопрос вроде короткий а цепь объяснений будет длинная и нюансов много)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines