在Linux中,我有一个带有“寄存器”的USB集线器,如下图所示。该寄存器应该禁用集线器上某个端口的电源。
我尝试使用LibUSB(我的代码如下所示)写入寄存器0x0A,所有零都禁用所有端口。问题是,集线器由标准Linux USB Hub驱动程序控制,因此内核驱动程序已分离。写也失败了。失败消息如下所示。
错误讯息:
$ /mnt/apps/UsbPowerControl
5 Devices in list.
Vendor:Device = 1908:1320
Vendor:Device = 0403:6001
Vendor:Device = 289d:0010
Vendor:Device = 0424:2513
Vendor:Device = 1d6b:0002
Opening Device = 0424:2513
Device Opened
Kernel Driver Active
Kernel Driver Detached!
Claimed Interface
Data-><-
Writing Data...
libusb: error [submit_bulk_transfer] submiturb failed error -1 errno=2
Write Error
Released Interface
如何使用LibUSB编写此Hub寄存器,动态禁用和启用端口,而无需取消注册Linux驱动程序并使写入失败?
#include <iostream>
#include <cassert>
#include <libusb-1.0/libusb.h>
using namespace std;
#define VENDOR_ID 0x0424
#define PRODUCT_ID 0x2513
int main() {
libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
libusb_device_handle *dev_handle; //a device handle
libusb_context *ctx = NULL; //a libusb session
int r; //for return values
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize the library for the session we just declared
if(r < 0) {
cout<<"Init Error "<<r<<endl; //there was an error
return 1;
}
libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
cout<<"Get Device Error"<<endl; //there was an error
return 1;
}
cout<<cnt<<" Devices in list."<<endl;
for (size_t idx = 0; idx < cnt; ++idx) {
libusb_device *device = devs[idx];
libusb_device_descriptor desc = {0};
int rc = libusb_get_device_descriptor(device, &desc);
assert(rc == 0);
printf("Vendor:Device = %04x:%04x\n", desc.idVendor, desc.idProduct);
}
printf("Opening Device = %04x:%04x\n", VENDOR_ID, PRODUCT_ID);
dev_handle = libusb_open_device_with_vid_pid(ctx, VENDOR_ID, PRODUCT_ID); //these are vendorID and productID I found for my usb device
if(dev_handle == NULL)
cout<<"Cannot open device"<<endl;
else
cout<<"Device Opened"<<endl;
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
unsigned char *data = new unsigned char[1]; //data to write
data[0]=0b00000000;
int actual; //used to find out how many bytes were written
if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached
cout<<"Kernel Driver Active"<<endl;
if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
cout<<"Kernel Driver Detached!"<<endl;
}
r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)
if(r < 0) {
cout<<"Cannot Claim Interface"<<endl;
return 1;
}
cout<<"Claimed Interface"<<endl;
cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to write : abcd
cout<<"Writing Data..."<<endl;
r = libusb_bulk_transfer(dev_handle, (0x0A | LIBUSB_ENDPOINT_OUT), data, 1, &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129
if(r == 0 && actual == 1) //we wrote the 1 bytes successfully
cout<<"Writing Successful!"<<endl;
else
cout<<"Write Error"<<endl;
r = libusb_release_interface(dev_handle, 0); //release the claimed interface
if(r!=0) {
cout<<"Cannot Release Interface"<<endl;
return 1;
}
cout<<"Released Interface"<<endl;
libusb_close(dev_handle); //close the device we opened
libusb_exit(ctx); //needs to be called to end the
delete[] data; //delete the allocated memory for data
return 0;
}
答案 0 :(得分:1)
// Registration Routes...
Route::get(LaravelLocalization::transRoute('routes.register_link')/{plan?}, ['as' => 'auth.register', 'uses' => 'Auth\AuthController@showRegistrationForm']);
Route::post(LaravelLocalization::transRoute('routes.register_link'), ['as' => 'auth.register', 'uses' => 'Auth\AuthController@postRegister']);
由于上面所写的内容,对“如何在不分离驱动程序的情况下执行I / O”这一问题的简短回答是“你不能”。
为什么写失败?这是另一回事。我建议你研究一些事情:
另外,我可以提出另一种解决方案的方法,即sysfs。
我假设your device(am I right?)支持EEPROM和SMBus访问。这意味着这个支持应该在 / sys / bus / i2c / devices / [some_device_id] / eeprom (可能是另一个设备号,另一个目录位置等)的内核中显示,因为它是全部驱动程序相关的),但如果它可以像任何其他文件一样被找到和读取(这很可能,除非设备出现问题),那么它也应该能够写入它。如果读取有效,那么我建议将找到的文件的 hexdump -C 与数据表进行比较,如果数据看似合法,请尝试直接写入寄存器(文件偏移量)。
无论如何,访问字符设备文件和sysfs文件是在linux中访问驱动程序数据的一般方法。可能你甚至不需要使用libusb的API来编写那个单字节。