Baca dalam bahasa Inggris

Bagikan melalui


Menggunakan Rutinitas IoTimer

Sementara timer untuk objek perangkat terkait diaktifkan, rutinitas IoTimer dipanggil sekitar sekali per detik. Namun, karena interval di mana setiap rutinitas IoTimer dipanggil tergantung pada resolusi jam sistem, jangan berasumsi bahwa rutinitas IoTimer akan dipanggil dengan tepat pada batas satu detik.

Catatan Rutinitas IoTimer , seperti semua rutinitas DPC, disebut di IRQL = DISPATCH_LEVEL. Sementara rutinitas DPC berjalan, semua utas dicegah berjalan pada prosesor yang sama. Pengembang driver harus dengan hati-hati merancang rutinitas IoTimer mereka untuk berjalan sesingkat mungkin.

Mungkin penggunaan yang paling umum untuk rutinitas IoTimer adalah kehabisan waktu operasi I/O perangkat untuk IRP. Pertimbangkan skenario berikut untuk menggunakan rutinitas IoTimer sebagai timer yang sedang berjalan dalam driver perangkat:

  1. Ketika memulai perangkat, driver menginisialisasi penghitung waktu di ekstensi perangkat ke -1, menunjukkan tidak ada operasi I/O perangkat saat ini, dan memanggil IoStartTimer tepat sebelum kembali STATUS_SUCCESS.

    Setiap kali rutinitas IoTimer dipanggil, ia memeriksa apakah penghitung timer adalah -1, dan, jika demikian, mengembalikan kontrol.

  2. StartIo driver rutin menginisialisasi penghitung waktu dalam ekstensi perangkat ke batas atas, ditambah detik tambahan jika rutinitas IoTimer baru saja dijalankan. Kemudian menggunakan KeSynchronizeExecution untuk memanggil rutinitas SynchCritSection_1 , yang memprogram perangkat fisik untuk operasi yang diminta oleh IRP saat ini.

  3. ISR driver mengatur ulang penghitung waktu ke -1 sebelum mengantre rutinitas DpcForIsr driver atau rutinitas CustomDpc .

  4. Setiap kali rutinitas IoTimer dipanggil, ia memeriksa apakah penghitung timer telah direset oleh ISR ke -1, dan, jika demikian, mengembalikan kontrol. Jika tidak, rutinitas IoTimer menggunakan KeSynchronizeExecution untuk memanggil rutinitas SynchCritSection_2 , yang menyesuaikan penghitung waktu oleh beberapa jumlah detik yang ditentukan driver.

  5. Rutinitas SynchCritSection_2 mengembalikan TRUE ke rutinitas IoTimer selama permintaan saat ini belum kehabisan waktu. Jika penghitung timer masuk ke nol, SynchCritSection_2 rutin mengatur ulang penghitung waktu ke nilai batas waktu reset yang ditentukan driver, menetapkan bendera yang diharapkan reset untuk dirinya sendiri (dan untuk DpcForIsr) di area konteksnya, mencoba mengatur ulang perangkat, dan mengembalikan TRUE.

    Rutinitas SynchCritSection_2 akan dipanggil lagi jika operasi resetnya juga kehabisan waktu pada perangkat, ketika kembali FALSE. Jika reset berhasil, rutinitas DpcForIsr menentukan bahwa perangkat telah direset dari bendera yang diharapkan reset dan mencoba kembali permintaan, mengulangi tindakan rutin StartIo seperti yang dijelaskan pada Langkah 2.

  6. Jika rutinitas SynchCritSection_2 mengembalikan FALSE, rutinitas IoTimer mengasumsikan perangkat fisik dalam keadaan tidak diketahui karena upaya untuk meresetnya telah gagal. Dalam keadaan ini, IoTimer rutin mengantrekan rutinitas CustomDpc dan kembali. Rutinitas CustomDpc ini mencatat kesalahan I/O perangkat, memanggil IoStartNextPacket, gagal dalam IRP saat ini, dan mengembalikan.

Jika ISR driver perangkat ini mengatur ulang penghitung waktu bersama ke -1, seperti yang dijelaskan dalam Langkah 3, rutinitas DpcForIsr driver menyelesaikan pemrosesan I/O yang digerakkan interupsi dari IRP saat ini. Penghitung timer reset menunjukkan bahwa operasi I/O perangkat ini belum kehabisan waktu, sehingga rutinitas IoTimer tidak perlu mengubah penghitung waktu.

Dalam kebanyakan keadaan, rutinitas SynchCritSection_2 sebelumnya hanya mengurangi penghitung timer. SynchCritSection_2 rutin mencoba mengatur ulang perangkat hanya jika operasi I/O saat ini telah kehabisan waktu, yang ditunjukkan ketika penghitung timer masuk ke nol. Dan hanya jika upaya untuk mengatur ulang perangkat telah gagal, SynchCritSection_2 rutin mengembalikan FALSE ke rutinitas IoTimer .

Akibatnya, rutinitas IoTimer sebelumnya dan pembantunya SynchCritSection_2 rutin membutuhkan waktu yang sangat sedikit untuk dieksekusi dalam keadaan normal. Dengan menggunakan rutinitas IoTimer dengan cara ini, driver perangkat memastikan bahwa setiap permintaan I/O perangkat yang valid dapat dicoba kembali, jika perlu, dan bahwa rutinitas CustomDpc akan gagal IRP hanya jika kegagalan perangkat keras yang tidak dapat dikoreksi mencegah IRP terpenuhi. Selain itu, driver menyediakan fungsionalitas ini dengan biaya yang sangat sedikit dalam waktu eksekusi.

Kesederhanaan skenario sebelumnya tergantung pada perangkat yang hanya melakukan satu operasi pada satu waktu dan pada driver yang biasanya tidak tumpang tindih operasi I/O. Driver yang melakukan operasi I/O perangkat yang tumpang tindih, atau driver tingkat yang lebih tinggi yang menggunakan rutinitas IoTimer untuk menyelesaikan serangkaian IRP yang dialokasikan driver yang dikirim ke lebih dari satu rantai driver yang lebih rendah, akan memiliki skenario batas waktu yang lebih kompleks untuk dikelola.