Aracılığıyla paylaş


Framework İş Öğelerini Kullanma

Bir iş öğesi, sürücünün EvtWorkItem olay geri çağırma fonksiyonunda gerçekleştirdiği bir görevdir. Bu işlevler, IRQL = PASSIVE_LEVEL düzeyinde, sistem işçi iş parçacığı bağlamında asenkron olarak çalışır.

Çerçeve tabanlı sürücüler, genellikle IRQL = DISPATCH_LEVEL'de çalışan bir EvtInterruptDpc veya EvtDpcFunc işlevi varsa ve IRQL = PASSIVE_LEVEL'de ek işlem gerçekleştirmesi gerekiyorsa iş birimlerini kullanır.

Başka bir deyişle, IRQL = DISPATCH_LEVEL çalışan bir işlevin yalnızca IRQL = PASSIVE_LEVEL'de çağrılabilen bir işlevi çağırması gerekiyorsa, sürücü iş öğelerini kullanabilir.

Genellikle bir sürücünün #B0 #A1 EvtInterruptDpc #A2 #C3 veya #B4 #A5 EvtDpcFunc #A6 #C7 geri çağırma işlevi bir iş öğesi nesnesi oluşturur ve bunu sistemin iş öğesi kuyruğuna ekler. Daha sonra, sistem işçi ipliği nesneyi sıradan çıkarır ve iş öğesinin EvtWorkItem geri çağırma işlevini çağırır.

İş Öğelerini Kullanan Örnek Sürücüler

#B0 1394, AMCC5933, PCIDRV ve Toaster gibi iş öğelerini kullanan örnek çerçeve tabanlı sürücüler bulunmaktadır.

Bir İş Öğesini Ayarlamak

bir iş öğesi ayarlamak için sürücünüzün şunları yapması gerekir:

  1. İş öğesini oluşturun.

    Sürücünüz, bir iş öğesi nesnesi oluşturmak ve iş öğesini işleyecek EvtWorkItem geri çağırma işlevini tanımlamak için WdfWorkItemCreate çağırır.

  2. İş öğesi hakkındaki bilgileri depolayın.

    Sürücüler genellikle EvtWorkItem geri çağırma fonksiyonunun gerçekleştirmesi gereken görev hakkındaki bilgileri depolamak için iş öğesi nesnesinin bağlam belleğini kullanır. #B0 EvtWorkItem#C1 geri çağırım işlevi çağrıldığında, bu bağlam belleğine erişip bilgileri alabilir. Bağlam belleğinin nasıl ayrıldığını ve erişildiğini öğrenmek için bkz. Framework Nesne Bağlam Alanı.

  3. İş öğesini sistemin iş öğesi kuyruğuna ekleyin.

    Sürücünüz, sürücünün iş öğesini iş öğesi kuyruğuna ekleyen WdfWorkItemEnqueue'u çağırır.

Sürücünüz #B0 #A1 WdfWorkItemCreate #A2 #A3 çağırdığında, bir çerçeve cihaz nesnesine veya çerçeve kuyruğu nesnesine tanıtıcı sağlamalıdır. Sistem bu nesneyi sildiğinde, nesneyle ilişkili mevcut iş öğelerini de siler. İlişkili iş öğesi geri çağırma, üst nesnenin EvtCleanupCallback geri çağırması çağrılmadan önce temizlenir ve iş öğesi nesnesi yok edilir.

Çerçeve nesnesi hiyerarşisinin temizleme kuralları hakkında daha fazla bilgi için bkz. #B0 Framework Nesne Yaşam Döngüsü #A1.

Work-Item Geri Çağırma İşlevini Kullanma

İş öğesi iş öğesi kuyruğuna eklendikten sonra, sistem çalışan iş parçacığı kullanılabilir duruma gelene kadar kuyrukta kalır. Sistem çalışan iş parçacığı iş öğesini kuyruktan kaldırır ve ardından sürücünün #B0 #A1 EvtWorkItem #A2 #C3 geri çağırma işlevini çağırarak iş öğesi nesnesini giriş olarak geçirir.

Genellikle EvtWorkItem geri çağırma işlevi aşağıdaki adımları gerçekleştirir:

  1. İş öğesi nesnesinin bağlam belleğine erişerek iş öğesi hakkında sürücü tarafından sağlanan bilgileri alır.

  2. Belirttiğiniz görevi gerçekleştirir. Gerekirse, geri çağırma işlevi, iş öğesinin ana nesnesini belirlemek için WdfWorkItemGetParentObject'ı çağırabilir.

  3. İş öğesi nesnesini silmek için WdfObjectDelete #A2 #C3 #B0 #A1 çağırır veya sürücü iş öğesini yeniden sorgulayacaksa, iş öğesinin tanıtıcısının artık yeniden kullanılabilir olduğunu gösterir.

Her iş öğesinin geri çağırma işlevinin gerçekleştirdiği görev görece kısa olmalıdır. İşletim sistemi sınırlı sayıda sistem çalışanı iş parçacığı sağlar, böylece sürücünüz zaman alan görevleri gerçekleştirmek için iş öğesi geri çağırma işlevlerini kullanıyorsa sistem performansını engelleyebilir.

İş Öğesi Oluşturma ve Silme

Sürücüler, iş öğelerini oluşturmak ve silmek için aşağıdaki iki teknikten birini kullanabilir:

  • Her iş öğesini bir kez kullanın: gerektiğinde iş öğesini oluşturun ve kullanıldıktan hemen sonra silin.

    Bu teknik, az sayıda iş öğesinin seyrek kullanımı (dakikada bir kezden az) gerektiren sürücüler için kullanışlıdır.

    Örneğin, bir sürücünün EvtInterruptDpc geri çağırma işlevi WdfWorkItemCreate çağırabilir ve ardından WdfWorkItemEnqueue, ve iş öğesinin EvtWorkItem geri çağırma işlevi WdfObjectDelete çağırabilir.

    Sürücünüz bu senaryoyu izlerse ve EvtInterruptDpc geri çağırma işlevi WdfWorkItemCreate'den STATUS_INSUFFICIENT_RESOURCES dönüş değeri alırsa, sürücü gerekli çalışmayı, sistem kaynakları (genellikle bellek) kullanılabilir olana kadar erteleyebilmelidir.

  • Sürücünüzün gerektiğinde yeniden kuyruğa aldığı bir veya daha fazla iş öğesi oluşturun.

    Bu teknik, iş öğelerini sık sık kullanan sürücüler (dakikada birden çok kez) veya sürücünüzün EvtInterruptDpc geri çağırma fonksiyonu WdfWorkItemCreate'den STATUS_INSUFFICIENT_RESOURCES durum değerini kolayca işleyemezse işletim açısından yararlıdır.

    Sistem, sürücü WdfWorkItemEnqueue çağırana kadar iş öğesine bir çalışan iş parçacığı ayırmaz. Bu nedenle, sistem çalışan iş parçacıkları sınırlı bir kaynak olsa da, bir cihazı başlatırken iş öğeleri oluşturmak az miktarda bellek tüketir, ancak sistem performansını etkilemez.

    Aşağıdaki adımlar olası bir senaryoyu açıklar:

    1. Sürücünün EvtDriverDeviceAdd geri çağırma işlevi, iş öğesi tanıtıcısını edinmek için WdfWorkItemCreate çağırır.
    2. Sürücünün EvtInterruptDpc geri çağırma işlevi, EvtWorkItem geri çağırma işlevinin gerçekleştirmesi gereken eylemlerin listesini oluşturur ve 1. adımdaki tanıtıcıyı kullanarak WdfWorkItemEnqueue çağırır.
    3. Sürücünün geriçağırma işlevi EvtWorkItem eylemleri gerçekleştirir ve işlevin çalıştığını belirtmek için bir bayrak ayarlar.

    Daha sonra, sürücünün EvtInterruptDpc callback işlevi her çağrıldığında, EvtWorkItem callback işlevinin çalıştığını belirlemesi gerekir. #B0 EvtWorkItem #C1 geri çağırma işlevi çalıştırılmadıysa, #B2 EvtInterruptDpc #C3 geri çağırma işlevi #B4 #A5 WdfWorkItemEnqueue #A6 #A7 çağırmaz çünkü iş öğesi hala kuyruktadır. Bu durumda, EvtInterruptDpc geri çağırma işlevi yalnızca EvtWorkItem geri çağırma işlevinin eylem listesini güncelleştirir.

    Her iş öğesi bir cihaz veya kuyrukla ilişkilendirilir. İlişkili cihaz veya kuyruk kaldırıldığında, framework ilişkili tüm iş öğelerini siler. Dolayısıyla, bu tekniği kullanıyorsanız, sürücünün WdfObjectDelete'i çağırmasına gerek yoktur.

Bazı sürücüler, iş öğelerini iş öğesi kuyruğundan temizlemek için WdfWorkItemFlush çağrısı yapmak zorunda kalabilirler. WdfWorkItemFlush örnek kullanım için yöntemin başvuru sayfasına bakın.

Sürücü, bekleyen bir iş öğesinde WdfObjectDelete çağrısı yaparsa, sonuç iş öğesinin durumuna bağlıdır.

İş öğesi durumu Sonuç
Oluşturuldu ama sıraya alınmadı İş öğesi derhal temizlenir.
Enqueued WdfObjectDelete çağrısı, iş unsuru tamamlanana kadar bekler, ardından iş unsuru temizlenir.
Yürütme Sürücü EvtWorkItem (aynı iş parçacığında) içinden WdfObjectDelete çalıştırırsa, WdfObjectDelete hemen döner. EvtWorkItem tamamlandığında, iş öğesi temizlenecektir. Aksi takdirde WdfObjectDelete, EvtWorkItem'in bitmesini bekler.