2018年7月7日 星期六

github hidapi hid_write fail on windows

windows 跟 linux 都預設支援 USB HID device dirver,也都有提供原生 API 讓開發者可以直接跟 HID device 溝通,github 上有一個專案 hidapi 提供了跨平台的方案,包含 windows 、linux 跟 MAC 上的 library,library 內部使用各平台的原生 HID API,並提供統一的 API 介面,讓開發者利用 hidapi 提供的介面,使程式有了在不同平台上的移植性

照理說那我們用 hidapi 後,程式不需修改只要重新編譯就可以跑在不同平台上,但最近卻遇到程式在 linux 上可以正常運作,在 windows 上卻出現 error 無法跑起來的情況

檢查後發現都是在呼叫 hidapi 的 hid_write 時該 function return error 值 -1,網路上搜尋後發現有很多人遇到類似的問題,有人就直接將 issue 回報給 hidapi 的作者,該 issue 最後也解決了,而且其實 hidapi 的作者在 API header 文件中就有說明呼叫 hid_write 需注意的地方



windows 上會出現 error 的原因是,windows 預期每一個 hid packet 第一個 byte 都是 report ID,假如你的 HID 裝置定義一個 HID report 的話,則那個值就會是 0,而我丟進去的 buffer 卻沒有把 report ID 加上去,所以就出現 fail 了

那為什麼在 linux 上卻沒問題呢?應該是因為 linux 平台的 libusb library 自動幫你把 report ID 0 加上去了,去看 hidapi 在 linux 上使用 libusb 的實作就可以發現,在 report id 是 0 的情況下,hidapi 反而把 report id 從 buffer 中拿掉了,就是因為如此,所以 linux 才不會出現 error



值得一提的是,windows 預設只接收滿足 longest report length 的 data,通常是 65,所以 hidapi 在 windows 的實作還會幫你檢查你傳進來的 buffer 大小是不是小於預期的 report length,如果是的話會幫你 create temp buffer 幫你補足 buffer 長度,因此 hid_write return 的值,也就是實際寫入到 device 的值會跟你傳進去的 buffer 大小不一樣

沒有留言:

張貼留言