USB Hid Raporları Hakkında

merakettim

Homo Sapiens Sapiens
Özel üye
HID, "Human Interface Device" kelimesinin kısaltması. Tükçesi "insan arabirim aygıtı". Agıt yöneticinizde, gördüğünüz bu isim altında listeleniyorlar. Amaçları ise adından da anlaşılacağı üzere insanlarla iletişim kurmaya yarayan aygıtlar.

Bunlardan en populerleri fare,klavye, oyun kolu,multimedya kumandası, dokunmatik ekren girdileri ve benzeri.

HID rapor tanımlayıcıları evrensellerdir ve aygıtın hangi veriyi, hangi sırada kaç bit göndereceğini açıklarlar ana bilgisayarlara. Yani bi aygıtın fare veya klavye olduğu durumda, bu aygıta uygun hid raporu tanımlayıcısı hazırlanması lazım. Usb ana bilgisayara usb aygıtı bağlandığında, gönderilen verilerin ne olduğunu öğrenmek ister. Mesela usb aygıtından bilgisayara 3 bayt veri gideceğini var sayalım ve bu veriler sırasıyla farenin tıklama durumu, farenin x ekseni ve farenin y ekseni olsun. İşte bu bilgileri ve sıralarını HID raporunda tanımlamamız lazım. Çok kullanılan işler için standartlar belirtilmiş ve usb aygıtı bilgisayara taktığımızda sürücü yüklemeden bilgisayar hemen tanıyor. Bu standartlara göre tanımlarsak bizim aygıtımız da sürücü yüklemeden tanınır. Şimdi sizlerle bir usb fare üretelim ve hid rapor tanımlayıcısını hazırlayalım.



Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
Bayt 0BoşBoşBoşBoşBoş Sol düğme Orta düğme Sağ düğme
Bayt 1İşaretliTamsayı OlarakX EkseniBağıl Hareketi
Bayt 2İşaretliTamsayı OlarakY Ekseni Bağıl Hareketi


Şeklinde bir veri yapımız olsun.

C deki hali

C:
struct mouse_report_t
{
 uint8_t buttons;
 int8_t x;
 int8_t y;
}

Şimdi HID raporu tanımlayıcımız yapalım.


İlk baytımız düme olacak şekilde tamınlamaya başlıyoruz.
Kod:
USAGE_PAGE (Button)
USAGE_MINIMUM (Button 1)
USAGE_MAXIMUM (Button 3)

Her düğme durumu bir bit, 0 veya 1 ile temsil edilir.
Kod:
LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1)

Bu parçalardan üç tane var (sol, orta ve sağ).
Kod:
REPORT_COUNT (3)
REPORT_SIZE (1)

Bu değişken verileri bilgisayara gönder.
Kod:
INPUT (Data,Var,Abs)




Düğmeleri temsil edecek kısım bura.
Kod:
USAGE_PAGE (Button)
USAGE_MINIMUM (Button 1)
USAGE_MAXIMUM (Button 3)
LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1)
REPORT_COUNT (3)
REPORT_SIZE (1)
INPUT (Data,Var,Abs)




ama beş tane boş dolgu bit var.
Kod:
REPORT_COUNT (1)
REPORT_SIZE (5)
INPUT (Cnst,Var,Abs)



Şimdi X ekseni hareketini yapıyoruz.
Kod:
USAGE_PAGE (Generic Desktop)
USAGE (X)


bir baytlık işaretli tamsayı olmasını istiyoruz, bu yüzden -127 ve +127 arasında bir değere sahip (aslında -128 ve +127, ama eşit olsun)
Kod:
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)


8 bitlik bir baytın tamamını almasını istiyoruz
Kod:
REPORT_SIZE (8)
REPORT_COUNT (1)


ve değişken bir göreceli koordinat olarak bilgisayara gönder.
Kod:
INPUT (Data,Var,Rel)


X ekseni hareketini temsil etmek için böyle bir şeyle çıkar.
Kod:
USAGE_PAGE (Generic Desktop)
USAGE (X)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (1)
INPUT (Data,Var,Rel)


Y eksenini de ekleyelim şimdi.
Kod:
USAGE_PAGE (Generic Desktop)
USAGE (X)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (1)
INPUT (Data,Var,Rel)
USAGE_PAGE (Generic Desktop)
USAGE (Y)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (1)
INPUT (Data,Var,Rel)


Yukardaki doğru bir rapor ama gereksiz fazlalıklar var.

Hafızadan tasarruf etmek için bunun yerine şöyle de yapabiliriz.
Kod:
USAGE_PAGE (Generic Desktop)
USAGE (X)
USAGE (Y)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (2)
INPUT (Data,Var,Rel)



Böylece tüm verilerimiz
Kod:
USAGE_PAGE (Button)
USAGE_MINIMUM (Button 1)
USAGE_MAXIMUM (Button 3)
LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM (1)
REPORT_COUNT (3)
REPORT_SIZE (1)
INPUT (Data,Var,Abs)
REPORT_COUNT (1)
REPORT_SIZE (5)
INPUT (Cnst,Var,Abs)
USAGE_PAGE (Generic Desktop)
USAGE (X)
USAGE (Y)
LOGICAL_MINIMUM (-127)
LOGICAL_MAXIMUM (127)
REPORT_SIZE (8)
REPORT_COUNT (2)
INPUT (Data,Var,Rel)


Hala bitmedi, bilgisayarın bunun bir fare olduğunu bilmesini sağlamak için
Kod:
USAGE_PAGE (Generic Desktop)
USAGE (Mouse)
COLLECTION (Application)
 USAGE (Pointer)
 COLLECTION (Physical)


 ... aygıtımızın fiziksel hareketleri buraya gelecek. Yukarıda yaptığımız yani.


 END COLLECTION
END COLLECTION


Sonuçta bu standart bir fare.

C:
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION

İşte gerçek bir fare yapmış olduk şimdi.

Son olarak belirtmeliyimki yukardaki fonksiyonları hex koda çevirmelisiniz. Bunun için usb.org adresinde bir uygulama paylaşmışlar.

 
Top