Программирование драйверов Windows


Исполняемый код драйвера - часть 8


//========================================================================= // Процедура обслуживания прерывания: // BOOLEAN Isr (IN PKINTERRUPT pInterruptObject, IN PVOID pServiceContext ) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pServiceContext; KIRQL currentIrql = KeGetCurrentIrql(); #if DBG==1 DbgPrint("LPTPORT: In Isr procedure, ISR_Irql=%d\n", currentIrql); #endif //=============================================================== // Строго говоря, следовало бы проверить, имело ли место // прерывание и наше ли это прерывание: // UCHAR status = ReadStatusRegister( pDevExt ); // if( status & 0x04 ) return FALSE; // прерывания не было // Однако в силу упомянутых накладок с использованием бита SR.2, // не проверяем это вовсе, делая допущение, что если Isr получила // управление, то прерывание vнаше. //=============================================================== // Общей практикой является блокирование поступления прерываний // в этом месте:

// WriteControlRegister( pDevExt, CR_DEFAULT);

// Однако, мы не будем этого делать, чтобы не испортить данные, // находящиеся сейчас в Status Register. Полагаем, что кроме // нашего драйвера такие прерывания никто не генерирует, а драйвер // защищен тем, что Write запросы отвергаются до полного переноса // данных. //================================================================ // Планируем вызов DPC процедуры для обработки прерывания позднее // KeInsertQueueDpc( &(pDevExt-&#62DpcForIsr_Object), (VOID *)NULL, // &#60- Arg1 in DpcForIsr (VOID *)NULL); // &#60- Arg2 in DpcForIsr return TRUE; // нормальное завершение обработки прерывания }

Процедура обработки прерывания Isr планирует вызов DpcForIsr DPC функции через размещение DPC объекта в системной очереди. Этим ее функции и ограничиваются в столь простом драйвере.

//========================================================================= // Код, который посылает в порт данные, вызывающие (при наличии // CheckIt заглушки) сигнал прерывания: // VOID ForceInterrupt( PDEVICE_EXTENSION pDevExt, UCHAR bits ) { // Генерируем сигнал прерывания WriteControlRegister( pDevExt, bits | CR_INT_ENB | CR_DEFAULT ); KeStallExecutionProcessor(50); // Удерживаем состояние 50 мкс // Удерживая информационные биты, снимаем импульс ACK# WriteControlRegister( pDevExt, bits | CR_INT_ENB | CR_NOT_RST | CR_DEFAULT ); KeStallExecutionProcessor(50); // Удерживаем состояние 50 мкс // Удерживая информационные биты, снимаем импульс ACK# WriteControlRegister( pDevExt, bits | CR_INT_ENB | CR_DEFAULT ); } //========================================================================= // Функция DoNextTransfer безопасно (от вмешательства кода прерывания, ISR // функции) записывает данные в параллельный порт: // BOOLEAN DoNextTransfer ( IN PVOID pContext ) {




Начало  Назад  Вперед