USB denetim aktarımı nasıl gönderilir

Bu makalede, bir denetim aktarımının yapısı ve istemci sürücüsünün cihaza nasıl denetim isteği göndermesi gerektiği açıklanmaktadır.

Varsayılan uç nokta hakkında

Tüm USB cihazları varsayılan uç nokta olarak adlandırılan en az bir uç noktayı desteklemelidir. Varsayılan uç noktayı hedefleyen her aktarıma denetim aktarımı denir. Denetim aktarımının amacı, konağın cihaz bilgilerini almasını, cihazı yapılandırmasını veya cihaza özgü denetim işlemlerini gerçekleştirmesini sağlamaktır.

Varsayılan uç noktanın bu özelliklerini inceleyerek başlayalım.

  • Varsayılan uç noktanın adresi 0'dır.
  • Varsayılan uç nokta çift yönlüdür, diğer bir ifadeyle konak uç noktaya veri gönderebilir ve tek bir aktarımda ondan veri alabilir.
  • Varsayılan uç nokta cihaz düzeyinde kullanılabilir ve cihazın hiçbir arabiriminde tanımlanmaz.
  • Varsayılan uç nokta, konak ve cihaz arasında bir bağlantı kurulduğu anda etkindir. Bir yapılandırma seçilmeden önce bile etkindir.
  • Varsayılan uç noktanın en büyük paket boyutu, cihazın veri yolu hızına bağlıdır. Düşük hız, 8 bayt; tam ve yüksek hız, 64 bayt; SuperSpeed, 512 bayt.

Denetim aktarımının düzeni

Denetim aktarımları yüksek öncelikli aktarımlar olduğundan, konak veri yolu üzerinde belirli miktarda bant genişliği ayırır. Düşük ve tam hızlı cihazlar için bant genişliğinin %10'u. Yüksek hızlı ve SuperSpeed aktarım yapabilen cihazlar için %20. Şimdi bir denetim aktarımının düzenine bakalım.

USB denetim aktarımı diyagramı.

Denetim aktarımı üç işleme ayrılır: kurulum işlemi, veri işlemi ve durum işlemi. Her işlem üç tür paket içerir: belirteç paketi, veri paketi ve el sıkışma paketi.

Bazı alanlar tüm paketler için ortaktır. Bu alanlar aşağıdaki gibidir:

  • Paketin başlangıcını gösteren eşitleme alanı.
  • Paket türünü, işlemin yönünü ve el sıkışma paketi söz konusu olduğunda işlemin başarılı veya başarısız olduğunu gösteren paket tanımlayıcısı (PID).
  • EOP alanı paketin sonunu gösterir.

Diğer alanlar paketin türüne bağlıdır.

Jeton paketi

Her kurulum işlemi bir belirteç paketiyle başlar. Paketin yapısı aşağıdadır. Sunucu her zaman belirteç paketini gönderir.

Belirteç paketi düzeninin diyagramı.

PID değeri belirteç paketinin türünü gösterir. Olası değerler şunlardır:

  • KURULUM: Denetim aktarımında kurulum işleminin başlangıcını gösterir.
  • IN: Konağın cihazdan veri isteğinde bulunduğunu gösterir (okuma durumu).
  • OUT: Konağın cihaza veri gönderdiğini gösterir (yazma durumu).
  • SOF: Çerçevenin başlangıcını gösterir. Bu tür bir belirteç paketi 11 bit çerçeve numarası içerir. Ana bilgisayar SOF paketini gönderir. Bu paketin gönderilme sıklığı veri yolu hızına bağlıdır. Tam hız için, ana bilgisayar paketi her 1 milisaniyede bir gönderir; yüksek hızlı bir otobüste 125 mikrosaniyede bir.

Veri paketi

Belirteç paketinin hemen ardından yükü içeren veri paketi gelir. Her veri paketinin içerebileceği bayt sayısı, varsayılan uç noktanın en büyük paket boyutuna bağlıdır. Veri paketi, aktarımın yönüne bağlı olarak konak veya cihaz tarafından gönderilebilir.

Veri paketi düzeninin diyagramı.

El sıkışma paketi

Veri paketinin hemen ardından el sıkışma paketi gelir. Paketin PID değeri, paketin konak veya cihaz tarafından alınıp alınmadığını gösterir. Aktarım yönüne bağlı olarak, el sıkışma paketi konak veya cihaz tarafından gönderilebilir.

El sıkışma paketi yapısının diyagramı.

Beagle, Ellisys, LeCroy USB protokol çözümleyicileri gibi herhangi bir USB çözümleyicisini kullanarak işlemlerin ve paketlerin yapısını görebilirsiniz. Çözümleyici cihazı, verilerin kablo üzerinden bir USB cihazına nasıl gönderildiğini veya alındığı gösterir. Bu örnekte, Bir LeCroy USB çözümleyicisi tarafından yakalanan bazı izleri inceleyelim. Bu örnek yalnızca bilgi içindir. Bu, Microsoft tarafından yapılan bir onay değildir.

Kurulum işlemi

Sunucu her zaman bir kontrol transferi başlatır. Bunu bir kurulum işlemi göndererek yapar. Bu işlem , kurulum belirteci adlı ve ardından 8 baytlık bir veri paketi içeren bir belirteç paketi içerir. Bu ekran görüntüsünde örnek bir kurulum işlemi gösterilir.

Kurulum işleminin izlemesinin ekran görüntüsü.

Yukarıdaki izlemede konak, kurulum belirteci paketi #434'ü göndererek denetim aktarımını başlatır ( H↓ile gösterilir). PID'in kurulum belirtecini belirten SETUP değerini belirttiğine dikkat edin. PID'yi cihaz adresi ve uç noktanın adresi izler. Denetim aktarımları için bu uç nokta adresi her zaman 0'dır.

Ardından, sunucu veri paketi #435'i gönderir. PID DATA0'dır ve bu değer paket sıralama için kullanılır (ele alınmalıdır). PID'nin ardından bu istekle ilgili ana bilgileri içeren 8 bayt geliyor. Bu 8 bayt, isteğin türünü ve cihazın yanıtını yazacağı arabelleğin boyutunu belirtir.

Tüm baytlar ters sırada alınır. Bölüm 9.3'te açıklandığı gibi şu alanları ve değerleri görüyoruz:

Saha Boyut Değer Açıklama
bmRequestType (Bkz. 9.3.1 bmRequestType) 1 0x80 Veri aktarım yönü cihazdan ana bilgisayaradır (D7 1'dir)

İstek standart bir istektir (D6... D5 0' dır)

İsteğin alıcısı CİhAZdir (D4 0'dır)
bRequest (Bkz. bölüm Bkz. 9.3.2 ve Tablo 9-4) 1 0x06 İstek türü GET_DESCRIPTOR.
wValue (Bkz. Tablo 9-5) 2 0x0100 İstek değeri, tanımlayıcı türünün DEVICE olduğunu gösterir.
wIndex (Bkz. bölüm 9.3.4) 2 0x0000 Yön ana bilgisayardan cihazadır (D7 1'dir)

Uç nokta numarası 0'dır.
wLength (Bkz. bölüm 9.3.5) 2 0x0012 İstek 18 bayt almaktır.

Bu nedenle, bu denetim (okuma) aktarımında ana bilgisayarın cihaz tanımlayıcısını almak için bir istek gönderdiği ve bu tanımlayıcıyı tutmak için aktarım uzunluğu olarak 18 bayt belirttiği sonucuna varabiliriz. Cihazın bu 18 baytı gönderme şekli, varsayılan uç noktanın bir işlemde gönderebileceği veri miktarına bağlıdır. Bu bilgiler, veri işlemine cihaz tarafından döndürülen cihaz tanımlayıcısında yer alır.

Yanıt olarak, cihaz bir el sıkışma paketi gönderir (#436 D↓tarafından gösterilir). PID değerinin ACK (ACK paketi) olduğuna dikkat edin. Bu, cihazın işlemi kabul ettiğini gösterir.

Veri işlemi

Şimdi cihazın isteğe yanıt olarak ne döndürdüğüne bakalım. Gerçek veriler bir veri işleminde aktarılır.

Veri işleminin izlemesi aşağıdadır.

Örnek bir veri işleminin izini gösteren ekran görüntüsü.

ACK paketini aldıktan sonra ana bilgisayar veri işlemini başlatır. İşlemi başlatmak için, IN yönünde (IN jetonu olarak adlandırılır) bir jeton paketi (#450) gönderir.

Yanıt olarak, cihaz IN belirtecini izleyen bir veri paketi (#451) gönderir. Bu veri paketi gerçek cihaz tanımlayıcısını içerir. İlk bayt, cihaz tanımlayıcısının uzunluğunu gösterir, 18 bayt (0x12). Bu veri paketindeki son bayt, varsayılan uç nokta tarafından desteklenen en büyük paket boyutunu gösterir. Bu durumda, cihazın varsayılan uç noktası üzerinden bir kerede 8 bayt gönderebildiğini görüyoruz.

Uyarı

Varsayılan uç noktanın en büyük paket boyutu, cihazın hızına bağlıdır. Yüksek hızlı bir cihazın varsayılan uç noktası 64 bayttır; düşük hızlı cihaz 8 bayttır.

Sunucu, cihaza bir ACK paketi (#452) göndererek veri işlemini onaylar.

Şimdi döndürülen veri miktarını hesaplayalım. Kurulum işleminde veri paketinin wLength alanında (#435), konak 18 bayt istedi. Veri işleminde cihazdan cihaz tanımlayıcısının yalnızca ilk 8 baytının alındığını görüyoruz. Peki, ana bilgisayar kalan 10 baytta depolanan bilgileri nasıl alır? Cihaz bunu iki işlemde yapar: 8 bayt ve ardından son 2 bayt.

Ana bilgisayar, varsayılan uç noktanın en büyük paket boyutunu öğrendiğine göre, yeni bir veri aktarımı başlatır ve paket boyutuna göre bir sonraki bölümü talep eder.

Bir sonraki veri işlemi aşağıdadır:

Yeni veri işleminin izlemesini gösteren ekran görüntüsü.

Ana bilgisayar, bir IN belirteci (#463) göndererek ve cihazdan sonraki 8 baytı isteyerek önceki veri aktarımını başlatır. Cihaz, cihaz tanımlayıcısının sonraki 8 baytını içeren bir veri paketi (#464) ile yanıt verir.

Ana bilgisayar, 8 baytı aldıktan sonra cihaza bir ACK paketi (#465) gönderir.

Ardından, konak başka bir veri işleminde aşağıdaki gibi son 2 bayt'ı istemektedir:

Konağın son 2 baytı istediği yeni örnek veri işleminin izini gösteren bir ekran görüntüsü.

Bu nedenle, cihazdan konağa 18 bayt aktarmak için konağın aktarılan bayt sayısını takip ettiğini ve üç veri işlemi başlattığını görüyoruz (8+8+2).

Uyarı

19, 23, 26 veri işlemlerinde veri paketlerinin PID'sine dikkat edin. PID, DATA0 ile DATA1 arasında geçiş sağlar. Bu diziye veri geçişi adı verilir. Birden çok veri işleminin olduğu durumlarda, paket sırasını doğrulamak için veri geçişi kullanılır. Bu yöntem, veri paketlerinin yinelenmemesini veya kaybolmamasını sağlar.

Birleştirilmiş veri paketlerini cihaz tanımlayıcısının yapısına eşleyerek (Bkz. Tablo 9-8), şu alanları ve değerleri görürüz:

Saha Boyut Değer Açıklama
bLength 1 0x12 18 bayt olan cihaz tanımlayıcısının uzunluğu.
bDescriptorType 1 0x01 Tanımlayıcı türü cihazdır.
bcdUSB 2 0x0100 Belirtim sürüm numarası 1.00'dır.
bDeviceClass 1 0x00 Cihaz sınıfı 0'dır. Yapılandırmadaki her arabirim sınıf bilgilerine sahiptir.
bDeviceSubClass 1 0x00 Cihaz sınıfı 0 olduğundan alt sınıf 0'dır.
bProtocol 1 0x00 Protokol 0'dır. Bu cihaz sınıfa özgü protokoller kullanmaz.
bMaxPacketSize0 1 0x08 Uç noktanın paket boyutu üst sınırı 8 bayttır.
idVendor 2 0x0562 Telex Communications.
idProduct 2 0x0002 USB mikrofonu.
bcdDevice 2 0x0100 Cihaz yayın numarasını gösterir.
iManufacturer 1 0x01 Üretici dizesi.
iProduct 1 0x02 Ürün dizisi.
iSerialNumber 1 0x03 Seri numarası.
bNumConfigurations 1 0x01 Yapılandırma sayısı.

Bu değerleri inceleyerek cihaz hakkında bazı ön bilgilere sahip olacağız. Cihaz düşük hızlı bir USB mikrofondur. Varsayılan uç noktanın en büyük paket boyutu 8 bayttır. Cihaz tek bir yapılandırmayı destekler.

İşlem Durumu

Son olarak, ana bilgisayar durum işlemini başlatarak kontrol aktarımını tamamlar.

Örnek veri işleminin izlemesinin ekran görüntüsü.

Ana bilgisayar işlemi bir OUT belirteç paketiyle (#481) başlatır. Bu paketin amacı, cihazın istenen tüm verileri gönderdiğini doğrulamaktır. Bu durum işleminde gönderilen veri paketi yok. Cihaz bir ACK paketiyle yanıt verir. Bir hata oluştuysa, PID NAK veya STALL olabilir.

Sürücü modelleri

Önkoşullar

İstemci sürücüsü kanalları numaralandıramadan önce bu gereksinimlerin karşılandığından emin olun:

  • İstemci sürücüsü çerçeve USB hedef cihaz nesnesini oluşturmuş olmalıdır.

    Microsoft Visual Studio Professional 2012 ile sağlanan USB şablonlarını kullanıyorsanız, şablon kodu bu görevleri gerçekleştirir. Şablon kodu hedef cihaz nesnesinin tutamacını alır ve cihaz bağlamında depolar.

KMDF istemci sürücüsü

KMDF istemci sürücüsünün WdfUsbTargetDeviceCreateWithParameters yöntemini çağırarak bir WDFUSBDEVICE tanıtıcısı alması gerekir. Daha fazla bilgi için bkz. USB istemci sürücü kodu yapısını anlama (KMDF)"Cihaz kaynak kodu".

UMDF istemci sürücüsü

UMDF istemci sürücüsü, çerçeve hedef cihaz nesnesini sorgulayarak bir IWDFUsbTargetDevice işaretçisi almalıdır. Daha fazla bilgi için USB istemci sürücü kodu yapısını (UMDF) anlama konusunda "IPnpCallbackHardware uygulaması ve USB'ye özgü görevler" bölümüne bakın.

Denetim aktarımının en önemli yönü, kurulum belirtecini uygun şekilde biçimlendirmektir. İsteği göndermeden önce şu bilgi kümesini toplayın:

  • İsteğin yönü: barındırıcıdan cihaza veya cihazdan barındırıcıya.
  • İsteğin alıcısı: cihaz, arabirim, uç nokta veya diğer.
  • İstek kategorisi: standart, sınıf veya satıcı.
  • İstek türü, GET_DESCRIPTPOR isteği gibi. Daha fazla bilgi için USB belirtiminde 9.5 bölümüne bakın.
  • wValue ve wIndex değerleri. Bu değerler isteğin türüne bağlıdır.

Tüm bu bilgileri resmi USB belirtiminden edinebilirsiniz.

UMDF sürücüsü yazıyorsanız OSR USB Fx2 Öğrenme Seti için UMDF Örnek Sürücüsü'nden Usb_hw.h üst bilgi dosyasını alın. Bu üst bilgi dosyası, denetim aktarımı için kurulum paketini biçimlendirmek için yararlı makrolar ve yapı içerir.

Tüm UMDF sürücülerinin, cihazlardan veri gönderip alabilmesi için çekirdek modu sürücüsüyle iletişim kurması gerekir. USB UMDF sürücüsü için çekirdek modu sürücüsü her zaman Microsoft tarafından sağlanan WinUSB sürücüsüdür (Winusb.sys).

BIR UMDF sürücüsü USB sürücü yığını için her istekte bulunduğunda, Windows G/Ç yöneticisi isteği WinUSB'ye gönderir. İsteği aldıktan sonra WinUSB isteği işler veya USB sürücü yığınına iletir.

Denetim aktarım istekleri göndermek için Microsoft tarafından tanımlanan yöntemler

Ana bilgisayarda bulunan bir USB istemci sürücüsü, cihaz hakkında bilgi almak, cihazı yapılandırmak veya üretici kontrol komutları göndermek için denetim isteklerini genellikle başlatır. Bu isteklerin tümü şu kategorilere ayrılmış olabilir:

  • Standart istekler USB belirtiminde tanımlanır. Standart istek göndermenin amacı cihaz, yapılandırmaları, arabirimleri ve uç noktaları hakkında bilgi edinmektir. Her isteğin alıcısı, isteğin türüne bağlıdır. Alıcı cihaz, arabirim veya uç nokta olabilir.

    Uyarı

    Herhangi bir denetim aktarımının hedefi her zaman varsayılan uç noktadır. Ana bilgisayarın tanımlayıcı, durum vb. gibi bilgileriyle ilgilendiği cihazla ilgili bir varlık, alıcıdır.

    İstekler şu şekilde sınıflandırılabilir: yapılandırma istekleri, özellik istekleri ve durum istekleri.

    • Yapılandırma istekleri, konağın cihazı yapılandırabilmesi için, GET_DESCRIPTOR isteği gibi bilgileri almak amacıyla cihaza gönderilir. Bu istekler, cihazda belirli bir yapılandırma veya alternatif ayar ayarlamak için konak tarafından gönderilen yazma istekleri de olabilir.
    • Özellik istekleri , cihaz, arabirim veya uç nokta tarafından desteklenen bazı Boole cihaz ayarlarını etkinleştirmek veya devre dışı bırakmak için istemci sürücüsü tarafından gönderilir.
    • Durum istekleri, konağın bir cihazın, uç noktanın veya arabirimin USB tanımlı durum bitlerini alabilmesini veya ayarlamasını sağlar.

    Daha fazla bilgi için bkz. BÖLÜM 9.4, USB belirtimi, sürüm 2.0. Standart istek türleri Usbspec.h üst bilgi dosyası olarak tanımlanır.

  • Sınıf istekleri belirli bir cihaz sınıfı belirtimi tarafından tanımlanır.

  • Satıcı istekleri satıcı tarafından sağlanır ve cihaz tarafından desteklenen isteklere bağlıdır.

Microsoft tarafından sağlanan USB yığını, önceki izlemelerde gösterildiği gibi cihazla tüm protokol iletişimini işler. Sürücü, bir istemci sürücüsünün denetim aktarımlarını birçok yolla göndermesini sağlayan cihaz sürücüsü arabirimlerini (DDI' ler) kullanıma sunar. İstemci sürücünüz bir Windows Driver Foundation (WDF) sürücüsüyse, sık kullanılan denetim isteği türlerini göndermek için yordamları doğrudan çağırabilir. WDF, hem KMDF hem de UMDF için denetim aktarımlarını içsel olarak destekler.

Bazı denetim isteği türleri WDF aracılığıyla kullanıma sunulmaz. bu istekler için istemci sürücüsü WDF-karma modelini kullanabilir. Bu model, istemci sürücüsünün WDM URB stilinde istekler oluşturup biçimlendirmesine ve ardından WDF çerçeve nesnelerini kullanarak bu istekleri göndermesine olanak tanır. Karma model yalnızca çekirdek modu sürücüleri için geçerlidir.

UMDF sürücüleri için:

usb_hw.h dosyasında tanımlanan yardımcı makroları ve yapıyı kullanın. Bu başlık, OSR USB Fx2 Öğrenme Seti için UMDF Örnek Sürücüsü ile birlikte verilir.

DENETIM isteklerini USB sürücü yığınına göndermenin en iyi yolunu belirlemek için bu tabloyu kullanın.

Bir denetim isteği göndermek istiyorsanız... KMDF sürücüsü için... UMDF sürücüsü için... WDM sürücüsü için bir URB yapısı oluşturun (yardımcı işlev)
CLEAR_FEATURE: Cihazdaki belirli özellik ayarlarını, yapılandırmalarını, arabirimlerini ve uç noktalarını devre dışı bırakın. USB belirtiminde bölüm 9.4.1'e bakın.
  1. Bir kurulum paketi tanımlayın. WDF_USB_CONTROL_SETUP_PACKET yapısına bakın.
  2. WDF_USB_CONTROL_SETUP_PACKET_INIT_FEATURE çağırarak kurulum paketini başlatın.
  3. WDF_USB_BMREQUEST_RECIPIENT içinde tanımlanan bir alıcı değeri belirtin.
  4. Özellik seçiciyi (wValue) belirtin. Bkz. Usbspec.h'de USB_FEATURE_XXX sabitleri. Ayrıca USB belirtiminde Tablo 9-6'ya bakın.
  5. SetFeature değerini FALSE olarak ayarlayın.
  6. WdfUsbTargetDeviceSendControlTransferSynchronously veya WdfUsbTargetDeviceFormatRequestForControlTransfer çağrısı yaparak isteği gönderin.
  1. Bir kurulum paketi tanımlayın. usb_hw.h'de bildirilen WINUSB_CONTROL_SETUP_PACKET yapısına bakın.
  2. usb_hw.h dosyasında tanımlanan WINUSB_CONTROL_SETUP_PACKET_INIT_FEATURE yardımcı makroyu çağırarak kurulum paketini başlatın.
  3. WINUSB_BMREQUEST_RECIPIENT'de tanımlanan bir alıcı değeri belirtin.
  4. Özellik seçiciyi (wValue) belirtin. Bkz USB_FEATURE_XXX sabitleri Usbspec.h. Ayrıca USB belirtiminde Tablo 9-6'ya bakın.
  5. SetFeature değerini FALSE olarak ayarlayın.
  6. Başlatılan kurulum paketini, IWDFUsbTargetDevice::FormatRequestForControlTransfer yöntemini çağırarak çerçeve talep nesnesi ve aktarım arabelleği ile ilişkilendirerek isteği oluşturun.
  7. IWDFIoRequest::Send yöntemini çağırarak isteği gönderin.
_URB_KONTROL_ÖZELLİK_İSTEMİ

(UsbBuildFeatureRequest)

URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE

URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE

URB_FONKSIYONU_ÖZELLİĞİ_SIFIRLA_İÇİN_UÇ NOKTAYA

URB_İŞLEV_DİĞERİNE_ÖZELLİĞİ_TEMİZLE
GET_CONFIGURATION: Geçerli USB yapılandırmasını alın. USB belirtiminde 9.4.2 bölümüne bakın. KMDF varsayılan olarak ilk yapılandırmayı seçer. Cihaz tanımlı yapılandırma numarasını almak için:

  1. bir WDF_USB_CONTROL_SETUP_PACKET biçimlendirin ve bRequest üyesini USB_REQUEST_GET_CONFIGURATION olarak ayarlayın.
  2. WdfUsbTargetDeviceSendControlTransferSynchronously veya WdfUsbTargetDeviceFormatRequestForControlTransfer çağrısı yaparak isteği gönderin.
UMDF varsayılan olarak ilk yapılandırmayı seçer. Cihaz tanımlı yapılandırma numarasını almak için:

  1. Bir kurulum paketi tanımlayın. usb_hw.h'de bildirilen WINUSB_CONTROL_SETUP_PACKET yapısına bakın.
  2. usb_hw.h dosyasında tanımlanan yardımcı makroyu (WINUSB_CONTROL_SETUP_PACKET_INIT) çağırarak kurulum paketini başlatın.
  3. Yön olarak BmRequestToDevice , alıcı olarak BmRequestToDevice ve istek olarak USB_REQUEST_GET_CONFIGURATION belirtin.
  4. IWDFUsbTargetDevice::FormatRequestForControlTransfer yöntemini çağırarak çerçeve isteği nesnesi ve aktarım arabelleği ile başlatılan kurulum paketini ilişkilendirip isteği oluşturun.
  5. IWDFIoRequest::Send yöntemini çağırarak isteği gönderin.
  6. Aktarım arabelleğindeki yapılandırma numarasını alın. IWDFMemory yöntemlerini çağırarak bu arabelleğe erişin.
_URB_CONTROL_GET_CONFIGURATION_REQUEST

URB_FONKSIYONU_AL_KONFİGÜRSYON
GET_DESCRIPTOR: Cihaz, yapılandırma, arabirim ve uç nokta tanımlayıcılarını alın. USB belirtiminde bölüm 9.4.3'e bakın.

Daha fazla bilgi için bkz. USB Tanımlayıcıları.
Şu yöntemleri çağır:

Şu yöntemleri çağır:

_URB_CONTROL_DESCRIPTOR_REQUEST

(UsbBuildGetDescriptorRequest)

URB_FONKSIYONU_CIHAZDAN_TANIMLAYICI_AL

Endpoint'tan Tanımlayıcı Alma İşlevi

URB_İŞLEV_ARAYÜZDEN_TANIMLAYICI_AL
GET_INTERFACE: Arabirim için geçerli alternatif ayarı alın. USB belirtiminde bölüm 9.4.4'e bakın.

  1. WdfUsbTargetDeviceGetInterface yöntemini çağırarak bir WDFUSBINTERFACE tanıtıcısı alın ve hedef arabirimi nesnesine erişin.
  2. WdfUsbInterfaceGetConfiguredSettingIndex yöntemini çağırın.
  1. Hedef arabirim nesnesi için bir IWDFUsbInterface işaretçisi edinin.
  2. IWDFUsbInterface::GetConfiguredSettingIndex yöntemini çağırın.
_URB_CONTROL_GET_INTERFACE_REQUEST

URB_FONKSİYONU_ARAYÜZÜ_AL
GET_STATUS: Bir cihazdan, uç noktadan veya arabirimden durum bitlerini alın. Bölüm 9.4.5'e bakın. usb belirtiminde.
  1. Bir kurulum paketi tanımlayın. WDF_USB_CONTROL_SETUP_PACKET yapısına bakın.
  2. WDF_USB_CONTROL_SETUP_PACKET_INIT_GET_STATUS çağırarak kurulum paketini başlatın.
  3. WDF_USB_BMREQUEST_RECIPIENT içinde tanımlanan alıcı değerini belirtin.
  4. Hangi durumu almak istediğinizi belirtin: cihaz, arabirim veya uç nokta (wIndex).
  5. WdfUsbTargetDeviceSendControlTransferSynchronously veya WdfUsbTargetDeviceFormatRequestForControlTransfer çağrısı yaparak isteği gönderin.
  1. Bir kurulum paketi tanımlayın. usb_hw.h'de bildirilen WINUSB_CONTROL_SETUP_PACKET yapısına bakın.
  2. usb_hw.h dosyasında tanımlanan yardımcı makro WINUSB_CONTROL_SETUP_PACKET_INIT_GET_STATUS çağırarak kurulum paketini başlatın.
  3. WINUSB_BMREQUEST_RECIPIENT'de tanımlanan bir alıcı değeri belirtin.
  4. Hangi durumu almak istediğinizi belirtin: cihaz, arabirim veya uç nokta (wIndex).
  5. IWDFUsbTargetDevice::FormatRequestForControlTransfer yöntemini çağırarak başlatılmış kurulum paketini, framework istek nesnesi ve transfer arabelleğiyle ilişkilendirerek isteği oluşturun.
  6. IWDFIoRequest::Send yöntemini çağırarak isteği gönderin.
  7. Aktarım arabelleğindeki durum değerini alın. Bu arabelleğe erişmek için IWDFMemory yöntemlerini çağırın.
  8. Durumun kendi kendine güçlendirilmiş, uzaktan uyandırmayı gösterip göstermediğini belirlemek için WINUSB_DEVICE_TRAITS numaralandırmasında tanımlanan değerleri kullanın:
_URB_CONTROL_GET_STATUS_REQUEST

(UsbBuildGetStatusRequest)

URB_FUNCTION_GET_STATUS_FROM_DEVICE

ARAYÜZDEN DURUM ALMA FONKSİYONU

URB_FONKSİYONU_BAĞLANTI_NOKTASINDAN_DURUM_AL

URB_FONKSIYONU_DİĞERİNDEN_DURUM_AL
SET_ADDRESS: USB belirtiminde bölüm 9.4.6'ya bakın. Bu istek USB sürücü yığını tarafından işlenir; istemci sürücüsü bu işlemi gerçekleştiremiyor. Bu istek USB sürücü yığını tarafından işlenir; istemci sürücüsü bu işlemi gerçekleştiremiyor. Bu istek USB sürücü yığını tarafından işlenir; istemci sürücüsü bu işlemi gerçekleştiremiyor.
SET_CONFIGURATION: Yapılandırma ayarlayın. USB belirtiminde bölüm 9.4.7'ye bakın.

Daha fazla bilgi için bkz. USB cihazı için yapılandırma seçme.
Varsayılan olarak KMDF, her arabirimde varsayılan yapılandırmayı ve ilk alternatif ayarı seçer. İstemci sürücüsü, WdfUsbTargetDeviceSelectConfigType yöntemini çağırarak ve istek seçeneği olarak WdfUsbTargetDeviceSelectConfigTypeUrb belirterek varsayılan yapılandırmayı değiştirebilir. Ardından bu istek için bir URB biçimlendirmeniz ve BUNU USB sürücü yığınına göndermeniz gerekir. Varsayılan olarak UMDF, her arabirimde varsayılan yapılandırmayı ve ilk alternatif ayarı seçer. İstemci sürücüsü yapılandırmayı değiştiremez. _URB_SELECT_CONFIGURATION

(USBD_SelectConfigUrbAllocateAndBuild)

URB_FONKSIYONU_SEÇ_KONFIGÜRASYONU
SET_DESCRIPTOR: Mevcut bir cihazı, yapılandırmayı veya dize tanımlayıcıyı güncelleştirin. USB belirtiminde bölüm 9.4.8'e bakın.

Bu istek yaygın olarak kullanılmaz. Ancak, USB sürücü yığını istemci sürücüsünden böyle bir istek kabul eder.
  1. İstek için bir URB ayırın ve oluşturun.
  2. Aktarım bilgilerini _URB_CONTROL_DESCRIPTOR_REQUEST bir yapıda belirtin.
  3. WdfUsbTargetDeviceFormatRequestForUrb veya WdfUsbTargetDeviceSendUrbSynchronously çağrısı yaparak isteği gönderin.
  1. Bir kurulum paketi tanımlayın. usb_hw.h'de bildirilen WINUSB_CONTROL_SETUP_PACKET yapısına bakın.
  2. AKTARıM bilgilerini USB belirtimine göre belirtin.
  3. IWDFUsbTargetDevice::FormatRequestForControlTransfer yöntemini çağırarak başlatılan kurulum paketini çerçeve isteği nesnesi ve aktarım arabelleğiyle ilişkilendirerek isteği derleyin.
  4. IWDFIoRequest::Send yöntemini çağırarak isteği gönderin.
_URB_CONTROL_DESCRIPTOR_REQUEST

URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE

Uç Noktaya Tanımlayıcı Ayarlama İşi (URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT)

URB_FUNCTION_ARAYÜZE_TANIMLAYICI_ATAMA_FUNCTION
SET_FEATURE: Cihazda, yapılandırmalarında, arabirimlerinde ve uç noktalarda belirli özellik ayarlarını etkinleştirin. USB belirtiminde 9.4.9 bölümüne bakın.
  1. Bir kurulum paketi tanımlayın. WDF_USB_CONTROL_SETUP_PACKET yapısına bakın.
  2. WDF_USB_CONTROL_SETUP_PACKET_INIT_FEATURE çağırarak kurulum paketini başlatın.
  3. WDF_USB_BMREQUEST_RECIPIENT'de tanımlanan alıcı değerini (cihaz, arabirim, uç nokta) belirtin.
  4. Özellik seçiciyi (wValue) belirtin. Bkz. Usbspec.h'de USB_FEATURE_XXX sabitleri. Ayrıca USB belirtiminde Tablo 9-6'ya bakın.
  5. SetFeature değerini TRUE olarak ayarlama
  6. WdfUsbTargetDeviceSendControlTransferSynchronously veya WdfUsbTargetDeviceFormatRequestForControlTransfer çağrısı yaparak isteği gönderin.
  1. Bir kurulum paketi tanımlayın. usb_hw.h'de bildirilen WINUSB_CONTROL_SETUP_PACKET yapısına bakın.
  2. usb_hw.h dosyasında tanımlanan WINUSB_CONTROL_SETUP_PACKET_INIT_FEATURE yardımcı makroyu çağırarak kurulum paketini başlatın.
  3. WINUSB_BMREQUEST_RECIPIENT'de tanımlanan bir alıcı değeri belirtin.
  4. Özellik seçiciyi (wValue) belirtin. Bkz USB_FEATURE_XXX sabitleri Usbspec.h. Ayrıca USB belirtiminde Tablo 9-6'ya bakın.
  5. SetFeature değerini TRUE olarak ayarlayın.
  6. Başlatılan kurulum paketini, framework istek nesnesi ve transfer arabelleği ile ilişkilendirip IWDFUsbTargetDevice::FormatRequestForControlTransfer yöntemini çağırarak isteği oluşturun.
  7. IWDFIoRequest::Send yöntemini çağırarak isteği gönderin.
_URB_CONTROL_FEATURE_REQUEST

(UsbBuildFeatureRequest)

URB_FONKSİYON_UNSUR_SET_CİHAZI

URB_FONKSİYON_ARAYÜZE_ÖZELLİK_ATA

URB_İŞLEV_UÇ_NOKTASINA_ÖZELLİK_ATAMA

URB_İŞLEVİ_ÖZELLİĞİ_BAŞKASINA_AYARLA
SET_INTERFACE: Arabirimdeki alternatif ayarı değiştirir. USB belirtiminde 9.4.9 bölümüne bakın.

Daha fazla bilgi için bkz. USB arabiriminde alternatif bir ayar seçme.
WdfUsbTargetDeviceSelectConfig
  1. Hedef arabirim nesnesi için bir WDFUSBINTERFACE tanıtıcısı alın.
  2. WdfUsbInterfaceSelectSetting yöntemini çağırın.
  1. Hedef arabirim nesnesi için bir IWDFUsbInterface işaretçisi edinin.
  2. IWDFUsbInterface::SelectSetting yöntemini çağırın.
_URB_SEÇME_ARAYÜZ

(USBD_SelectInterfaceUrbAllocateAndBuild)

URB_FUNCTION_ARAYÜZ_SEÇme
SYNC_FRAME: Bir uç noktasının eşitleme çerçeve numarasını ayarlayın ve alın. USB belirtiminde 9.4.10 bölümüne bakın. Bu istek USB sürücü yığını tarafından işlenir; istemci sürücüsü bu işlemi gerçekleştiremiyor. Bu istek USB sürücü yığını tarafından işlenir; istemci sürücüsü bu işlemi gerçekleştiremiyor. Bu istek USB sürücü yığını tarafından işlenir; istemci sürücüsü bu işlemi gerçekleştiremiyor.
Belirli cihaz sınıfı talepleri ve tedarikçi komutları için.
  1. Bir kurulum paketi tanımlayın. WDF_USB_CONTROL_SETUP_PACKET yapısına bakın.
  2. Kurulum paketini başlatmak için, WDF_USB_CONTROL_SETUP_PACKET_INIT_CLASS sınıfına özgü istekleri veya satıcı komutları için WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR işlevini çağırın.
  3. WDF_USB_BMREQUEST_RECIPIENT'de tanımlanan alıcı değerini (cihaz, arabirim, uç nokta) belirtin.
  4. WdfUsbTargetDeviceSendControlTransferSynchronously veya WdfUsbTargetDeviceFormatRequestForControlTransfer çağrısı yaparak isteği gönderin.
  1. Bir kurulum paketi tanımlayın. usb_hw.h'de bildirilen WINUSB_CONTROL_SETUP_PACKET yapısına bakın.
  2. usb_hw.h dosyasında tanımlanan WINUSB_CONTROL_SETUP_PACKET_INIT_CLASS veyaWINUSB_CONTROL_SETUP_PACKET_INIT_VENDOR yardımcı makroyu çağırarak kurulum paketini başlatın.
  3. Sınıfı veya donanım belirtiminde açıklandığı gibi yönü ( bkz. WINUSB_BMREQUEST_DIRECTION numaralandırması), alıcıyı ( WINUSB_BMREQUEST_RECIPIENT numaralandırmaya bakın) ve isteği belirtin.
  4. IWDFUsbTargetDevice::FormatRequestForControlTransfer yöntemini çağırarak başlatılan kurulum paketini, çerçeve isteği nesnesi ve aktarım arabelleğiyle ilişkilendirip isteği oluşturun.
  5. IWDFIoRequest::Send yöntemini çağırarak isteği gönderin.
  6. Aktarım arabelleğindeki cihazdan bilgileri alın. IWDFMemory yöntemlerini çağırarak bu arabelleğe erişin.
_URB_CONTROL_VENDOR_OR_CLASS_REQUEST (Satıcı veya Sınıf İstek Kontrolü)

(UsbVendorİstekOluştur)

URB_FONKSIYON_VENDOR_CIHAZ

URB_FONKSİYONU_SATICI_ARAYÜZÜ

URB_FUNCTION_VENDOR_ENDPOINT (Satıcı Bitim Noktası İşlevi)

Satıcı Diğer URB İşlevi

URB_FUNCTION_CLASS_DEVICE

URB_FUNCTION_CLASS_INTERFACE

URB_FUNCTION_CLASS_ENDPOINT

URB_FONKSİYON_SINIF_DIĞER

KMDF - Satıcı komutları için kontrol transferi gönderme

Bu yordam, bir istemci sürücüsünün nasıl denetim aktarımı gönderebileceğini gösterir. Bu örnekte, istemci sürücüsü, cihazdan üretici yazılımı sürümünü almak için bir üretici komutu gönderir.

  1. Satıcı komutu için bir sabit değer bildirin. Donanım belirtimini inceleyin ve kullanmak istediğiniz satıcı komutunu belirleyin.

  2. WDF_MEMORY_DESCRIPTOR bir yapı bildirin ve WDF_MEMORY_DESCRIPTOR_INIT_BUFFER makroyu çağırarak bu yapıyı başlatın. Bu yapı, USB sürücüsü isteği tamamladıktan sonra cihazdan yanıt alır.

  3. İsteği zaman uyumlu mu yoksa zaman uyumsuz olarak mı gönderdiğinize bağlı olarak, gönderme seçeneklerinizi belirtin:

  4. Kurulum belirtecini içerecek bir WDF_USB_CONTROL_SETUP_PACKET yapısı bildirin ve yapıyı biçimlendirin. Bunu yapmak için WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR makroyu çağırarak kurulum paketini biçimlendirin. Çağrıda isteğin yönünü, alıcıyı, gönderilen istek seçeneklerini (adım3'te başlatılır) ve satıcı komutunun sabitini belirtin.

  5. WdfUsbTargetDeviceSendControlTransferSynchronously veya WdfUsbTargetDeviceFormatRequestForControlTransfer çağrısı yaparak isteği gönderin.

  6. Çerçeve tarafından döndürülen NTSTATUS değerini denetleyin ve alınan değeri inceleyin.

Bu kod örneği, bir USB cihazından üretici yazılım sürümünü getirmek için bir denetim aktarım isteği gönderir. İstek zaman uyumlu olarak gönderilir ve istemci sürücüsü 5 saniyelik göreli bir zaman aşımı değeri belirtir (100 nanosaniye cinsinden). Sürücü, alınan yanıtı sürücü tanımlı cihaz bağlamında depolar.

enum {
    USBFX2_GET_FIRMWARE_VERSION = 0x1,
....

} USBFX2_VENDOR_COMMANDS; 

#define WDF_TIMEOUT_TO_SEC              ((LONGLONG) 1 * 10 * 1000 * 1000)  // defined in wdfcore.h

const __declspec(selectany) LONGLONG
            DEFAULT_CONTROL_TRANSFER_TIMEOUT = 5 * -1 * WDF_TIMEOUT_TO_SEC; 


typedef struct _DEVICE_CONTEXT
{

    ...
       union {
        USHORT      VersionAsUshort;
        struct {
            BYTE Minor;
            BYTE Major;
        } Version;
    } Firmware; // Firmware version.

} DEVICE_CONTEXT, *PDEVICE_CONTEXT;


__drv_requiresIRQL(PASSIVE_LEVEL)
VOID  GetFirmwareVersion(
    __in PDEVICE_CONTEXT DeviceContext
)
{
    NTSTATUS                        status;
    WDF_USB_CONTROL_SETUP_PACKET    controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS        sendOptions;
    USHORT                          firmwareVersion;
    WDF_MEMORY_DESCRIPTOR           memoryDescriptor;

    PAGED_CODE();

    firmwareVersion = 0;

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDescriptor, (PVOID) &firmwareVersion, sizeof(firmwareVersion));

    WDF_REQUEST_SEND_OPTIONS_INIT(
                                  &sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT
                                  );

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
                                         &sendOptions,
                                         DEFAULT_CONTROL_TRANSFER_TIMEOUT
                                         );

    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestDeviceToHost,       // Direction of the request
                                        BmRequestToDevice,           // Recipient
                                        USBFX2_GET_FIRMWARE_VERSION, // Vendor command
                                        0,                           // Value
                                        0);                          // Index 

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                        DeviceContext->UsbDevice,
                                        WDF_NO_HANDLE,               // Optional WDFREQUEST
                                        &sendOptions,
                                        &controlSetupPacket,
                                        &memoryDescriptor,           // MemoryDescriptor
                                        NULL);                       // BytesTransferred 

    if (!NT_SUCCESS(status)) 
    {
        KdPrint(("Device %d: Failed to get device firmware version 0x%x\n", DeviceContext->DeviceNumber, status));
        TraceEvents(DeviceContext->DebugLog,
                    TRACE_LEVEL_ERROR,
                    DBG_RUN,
                    "Device %d: Failed to get device firmware version 0x%x\n",
                    DeviceContext->DeviceNumber,
                    status);
    }
    else 
    {
        DeviceContext->Firmware.VersionAsUshort = firmwareVersion;
        TraceEvents(DeviceContext->DebugLog,
                    TRACE_LEVEL_INFORMATION,
                    DBG_RUN,
                    "Device %d: Get device firmware version : 0x%x\n",
                    DeviceContext->DeviceNumber,
                    firmwareVersion);
    }

    return;
}

GET_STATUS için denetim aktarımı gönderme - UMDF

Bu yordam, istemci sürücüsünün bir GET_STATUS komutu için nasıl denetim aktarımı gönderebileceğini gösterir. İsteğin alıcısı cihazdır ve istek D1-D0 bitlerinde bilgi alır. Daha fazla bilgi için USB belirtimindeki Şekil 9-4'e bakın.

  1. OSR USB Fx2 Öğrenme Seti için UMDF Örnek Sürücüsü ile kullanılabilen Usb_hw.h üst bilgi dosyasını ekleyin.

  2. WINUSB_CONTROL_SETUP_PACKET bir yapı bildirin.

  3. Yardımcı makroyu çağırarak kurulum paketini başlatın WINUSB_CONTROL_SETUP_PACKET_INIT_GET_STATUS.

  4. Alıcı olarak BmRequestToDevice değerini belirtin.

  5. Dizin değerinde 0 değerini belirtin.

  6. İsteği zaman uyumlu olarak göndermek için SendControlTransferSynchronously yardımcı yöntemini çağırın.

    Yardımcı yöntemi, IWDFUsbTargetDevice::FormatRequestForControlTransfer yöntemini çağırarak başlatılan kurulum paketini çerçeve isteği nesnesi ve aktarım arabelleğiyle ilişkilendirerek isteği oluşturur. Yardımcı yöntem daha sonra IWDFIoRequest::Send yöntemini çağırarak isteği gönderir. Yöntemi döndürdükten sonra döndürülen değeri inceleyin.

  7. Durumun kendi kendine güçlendirilmiş, uzaktan uyandırmayı gösterip göstermediğini belirlemek için WINUSB_DEVICE_TRAITS numaralandırmasında tanımlanan şu değerleri kullanın:

Bu kod örneği, cihazın durumunu almak için bir denetim aktarım isteği gönderir. Örnek, SendControlTransferSynchronously adlı bir yardımcı yöntemi çağırarak isteği zaman uyumlu olarak gönderir.

HRESULT
CDevice::GetDeviceStatus ()
{

    HRESULT hr = S_OK;

    USHORT deviceStatus;
    ULONG bytesTransferred;

    TraceEvents(TRACE_LEVEL_INFORMATION,
                DRIVER_ALL_INFO,
                "%!FUNC!: entry");

    // Setup the control packet.

    WINUSB_CONTROL_SETUP_PACKET setupPacket;

    WINUSB_CONTROL_SETUP_PACKET_INIT_GET_STATUS(
                                      &setupPacket,
                                      BmRequestToDevice,
                                      0);

    hr = SendControlTransferSynchronously(
                 &(setupPacket.WinUsb),
                 & deviceStatus,
                 sizeof(USHORT),
                 &bytesReturned
                );

     if (SUCCEEDED(hr))
    {
        if (deviceStatus & USB_GETSTATUS_SELF_POWERED)
        {
             m_Self_Powered = true;
        } 
        if (deviceStatus & USB_GETSTATUS_REMOTE_WAKEUP_ENABLED)
        {
             m_remote_wake-enabled = true;
        }
    }

    return hr;
 }

Aşağıdaki kod örneğinde SendControlTransferSynchronously adlı yardımcı yöntemin uygulanması gösterilmektedir. Bu yöntem bir isteği zaman uyumlu olarak gönderir.

HRESULT
CDevice::SendControlTransferSynchronously(
    _In_ PWINUSB_SETUP_PACKET SetupPacket,
    _Inout_ PBYTE Buffer,
    _In_ ULONG BufferLength,
    _Out_ PULONG LengthTransferred
    )
{
    HRESULT hr = S_OK;
    IWDFIoRequest *pWdfRequest = NULL;
    IWDFDriver * FxDriver = NULL;
    IWDFMemory * FxMemory = NULL;
    IWDFRequestCompletionParams * FxComplParams = NULL;
    IWDFUsbRequestCompletionParams * FxUsbComplParams = NULL;

    *LengthTransferred = 0;

    hr = m_FxDevice->CreateRequest( NULL, //pCallbackInterface
                                    NULL, //pParentObject
                                    &pWdfRequest);

    if (SUCCEEDED(hr))
    {
        m_FxDevice->GetDriver(&FxDriver);

        hr = FxDriver->CreatePreallocatedWdfMemory( Buffer,
                                                    BufferLength,
                                                    NULL,        //pCallbackInterface
                                                    pWdfRequest, //pParetObject
                                                    &FxMemory );
    }

    if (SUCCEEDED(hr))
    {
        hr = m_pIUsbTargetDevice->FormatRequestForControlTransfer( pWdfRequest,
                                                                   SetupPacket,
                                                                   FxMemory,
                                                                   NULL); //TransferOffset
    }

    if (SUCCEEDED(hr))
    {
        hr = pWdfRequest->Send( m_pIUsbTargetDevice,
                                WDF_REQUEST_SEND_OPTION_SYNCHRONOUS,
                                0); //Timeout
    }

    if (SUCCEEDED(hr))
    {
        pWdfRequest->GetCompletionParams(&FxComplParams);

        hr = FxComplParams->GetCompletionStatus();
    }

    if (SUCCEEDED(hr))
    {
        HRESULT hrQI = FxComplParams->QueryInterface(IID_PPV_ARGS(&FxUsbComplParams));
        WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI));

        WUDF_TEST_DRIVER_ASSERT( WdfUsbRequestTypeDeviceControlTransfer ==
                            FxUsbComplParams->GetCompletedUsbRequestType() );

        FxUsbComplParams->GetDeviceControlTransferParameters( NULL,
                                                             LengthTransferred,
                                                             NULL,
                                                             NULL );
    }

    SAFE_RELEASE(FxUsbComplParams);
    SAFE_RELEASE(FxComplParams);
    SAFE_RELEASE(FxMemory);

    pWdfRequest->DeleteWdfObject(); 
    SAFE_RELEASE(pWdfRequest);

    SAFE_RELEASE(FxDriver);

    return hr;
}

cihazınızın işlev sürücüsü olarak Winusb.sys kullanıyorsanız, bir uygulamadan denetim aktarımları gönderebilirsiniz. WinUSB'de kurulum paketini biçimlendirmek için, bu makaledeki tabloda açıklanan UMDF yardımcı makrolarını ve yapılarını kullanın. İsteği göndermek için WinUsb_ControlTransfer işlevini çağırın.