linux下hid设备读写的问题

zhuruibing 2011-06-22 11:10:56
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/hid.h>
#include <linux/hiddev.h>
int main(int argc,char **argv)
{
int fd;
int rtn,ret=0;
int i,j=0;
struct hiddev_report_info rinfo;
struct hiddev_usage_ref uref;
struct hiddev_field_info finfo;
struct hiddev_usage_ref_multi urefs;
struct hiddev_devinfo dinfo;
struct hiddev_collection_info cinfo;
unsigned char bufw[21]={0x02,0x08,0xce,0,0,0,0,0,0,0};
unsigned char recv[21]={0};
//printf("argc = %d\n",argc);
//打开设备文件
fd=open("/dev/usb/hiddev0",O_RDWR);
if(fd > 0)
{
printf("open hid success!,fd = %d\n",fd);
}
//
rinfo.report_type=HID_REPORT_TYPE_OUTPUT;
rinfo.report_id=HID_REPORT_ID_FIRST;
ret=ioctl(fd,HIDIOCGREPORTINFO,&rinfo);
if(ret != 0)
{
printf("ioctl one failed!\n");
close(fd);
return -1;
}
for(i=0;i<rinfo.num_fields;i++)
{
finfo.report_type=rinfo.report_type;
finfo.report_id=rinfo.report_id;
finfo.field_index=i;
ret = ioctl(fd,HIDIOCGFIELDINFO,&finfo);
printf("finfo.maxusage %d\n",finfo.maxusage);
if(ret != 0)
{
printf("ioctl two failed\n");
close(fd);
return -1;
}
//for(j=0;j<finfo.maxusage;j++)
//{
uref.report_type=finfo.report_type;
uref.report_id=finfo.report_id;
uref.field_index=i;
uref.usage_index=j;//ioctl(fd,HIDIOCGUCODE,&uref);
ret = ioctl(fd,HIDIOCGUSAGE,&uref);
if(ret != 0)
{
printf("ioctl three faile!\n");
close(fd);
return -1;
}
ret = ioctl(fd,HIDIOCGUCODE,&uref);
printf("usage.value:%x\n",uref.value);
printf("usage report_type %d report_id %d field_index %d usage_index %d usage_code %d\n",
uref.report_type, uref.report_id, uref.field_index, uref.usage_index, uref.usage_code);
if(ret != 0)
{
printf("ioctl four failed\n");
close(fd);
return -1;
}
printf("\n");
//}
urefs.uref.report_type=HID_REPORT_TYPE_OUTPUT;
urefs.uref.report_id=finfo.report_id;
urefs.num_values=8;
urefs.uref.field_index=i;
urefs.uref.usage_index=0;
for(j=0;j<21;j++)
{
urefs.uref.usage_code+=4;
urefs.values[j]=bufw[j];
printf("usage report_type:%d,report_id:%d,field_index:%d,usage_index:%d,usage_code:%d\n", urefs.uref.report_id,urefs.uref.report_id,urefs.uref.field_index,urefs.uref.usage_index, urefs.uref.usage_code);
}
ret=ioctl(fd,HIDIOCSUSAGES,&urefs);//写入数据1
if(ret !=0)
{
printf("failed !\n");
close(fd);
return -1;
}
}
rinfo.report_type=HID_REPORT_TYPE_INPUT;
rinfo.report_id=HID_REPORT_ID_FIRST;
for(i=0;i<rinfo.num_fields;i++)
{
printf("num_field=%d\n",rinfo.num_fields);
finfo.report_type=rinfo.report_type;
finfo.report_id=rinfo.report_id;
finfo.field_index=i;
printf("finfo.report_id:%d\n",finfo.report_id);
ret =ioctl(fd,HIDIOCGFIELDINFO,&finfo);
if(ret !=0)
{
printf("ioctl five faile!\n");
close(fd);
return -1;
}
else
{
printf("finfo.report_id:%d\n",finfo.report_id);
}
}
for(i=0;i<21;i++)//打印结构体中是否有值。运行之后显示正确
{
printf("%3x",urefs.values[i]);
}
printf("\n");
ret=ioctl(fd,HIDIOCINITREPORT,0);
printf("ret = %d\n",ret);
memset(urefs.values,0,sizeof(urefs.values));//将结构体中用来存储数据的urefs.values置空
for(i=0;i<21;i++)
printf("%3x",urefs.values[i]);
ret=ioctl(fd,HIDIOCGUSAGES,&urefs);//接收数据,程序运行正确
printf("ret = %d\n",ret);
for(i=0;i<21;i++)//打印接收的值,运行后结果没有变,还是bufw的值
{
printf("%3x",urefs.values[i]);
}
printf("\n");
close(fd);
return 0;
}
编译通过,同时通过ioctl可以得到设备的相关信息,但是接收数据却是打印出原先bufw的值。如果要是和硬件通信成功,返回的应该是硬件返回到上层的值,在xp下用Bus Hound测得由硬件返回的值是{0x01,0x08,0xc8,0xca,0x00,0xff,0}。请问是错在哪里了?为何用ioctl接收到的值是错的?请各位指导下小弟。谢谢!
...全文
2288 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
星号 2013-12-18
  • 打赏
  • 举报
回复
楼主,怎么进行读写啊,是对单个端点读写吗,能把你实现的代码都贴出来吗,谢谢无私的奉献啊。。。
hunter0395 2012-11-17
  • 打赏
  • 举报
回复
另外libusb对于一个interface中做了多个collection的设备来说就有可能达不到目的。因为可能存在希望linux接管的collection。
hunter0395 2012-11-17
  • 打赏
  • 举报
回复
楼主操作不成功的原因是缺少HIDIOCSREPORT和HIDIOCGREPORT两个步骤。
zhuruibing 2012-11-01
  • 打赏
  • 举报
回复
需要另外下载,与系统无关
cloudborn 2012-10-08
  • 打赏
  • 举报
回复
楼主,请问libusb是系统自带的,还是要另外下载的?还有这与系统版本有关系吗?
zhuyouleixuexi 2012-08-31
  • 打赏
  • 举报
回复
我看看
zhuruibing 2012-03-09
  • 打赏
  • 举报
回复
使用libusb,具体如下:
1 打开设备:

usb_init();
nret=usb_find_busses();
if(nret<0)
{
sprintf(g_buf,"usb_find_busses nret:[%d] fail:[%s]",nret,strerror(errno));
return (*env)->NewStringUTF(env,g_buf);
}
nret1=nret;
nret=usb_find_devices();
if(nret<0)
{
sprintf(g_buf,"nret1:[%d] usb_find_devices nret:[%d] fail:[%s]",nret1,nret,strerror(errno));
return (*env)->NewStringUTF(env,g_buf);
}

#ifdef myhid_debug
sprintf(g_buf,"libenkb:usb_find_busses[%d] usb_find_devices[%d]\n",nret1,nret);
writelog(g_buf);
#endif

for (bus = usb_busses; bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
if(dev->descriptor.idVendor==VENDOR_ID&& dev->descriptor.idProduct == PRODUCT_ID)
{
findflag=1;
goto find_ok;
}
}
}

if(findflag==0)
{
return (*env)->NewStringUTF(env, "hid device not find!");
}


find_ok:
udev=usb_open(dev);
if(udev==NULL)
{
return (*env)->NewStringUTF(env,"hid open fail!");
}

#ifdef myhid_debug
sprintf(g_buf,"idVendor:0x%x idProduct:0x%0x iManufacturer:%d bNumEndpoints:0x%0x",dev->descriptor.idVendor,dev->descriptor.idProduct,dev->descriptor.iManufacturer,dev->config->interface->altsetting->bNumEndpoints);
writelog(g_buf);
#endif

nret=usb_detach_kernel_driver_np(udev,0);

/*
if(nret<0)
{
sprintf(g_buf,"usb_detach_kernel_driver_np nret:[%d] fail:[%s]",nret,strerror(errno));
return (*env)->NewStringUTF(env,g_buf);
}
*/

nret=usb_claim_interface(udev,0);

2 关闭设备

int nret=usb_release_interface(udev,0);
if(nret<0)
{
sprintf(g_buf,"usb_release_interface nret:[%d] fail:[%s]",nret,strerror(errno));
return (*env)->NewStringUTF(env,g_buf);
}

nret=usb_close(udev);
if(nret<0)
{
sprintf(g_buf,"usb_close ret:[%d] fail:[%s]",nret,strerror(errno));
return (*env)->NewStringUTF(env,g_buf);
}

其它就简单了
写入用usb_interrupt_write
读取用usb_interrupt_read
anthony5000 2012-02-17
  • 打赏
  • 举报
回复
想问楼主是怎么解决的啊
z_rb28 2011-06-27
  • 打赏
  • 举报
回复
使用libusb很简单
zhuruibing 2011-06-27
  • 打赏
  • 举报
回复
已经解决,结贴
thunder__god 2011-06-23
  • 打赏
  • 举报
回复
学习中,帮顶
zhuruibing 2011-06-22
  • 打赏
  • 举报
回复
网上有各种各样读写HID设备的源代码例子,有的是通过HIDIOCSUSAGE和HIDIOCGUSAGE来每次收发4个字节,适合鼠标、键盘之类数据传输量小的设备;有的是通过HIDIOCSUSAGES和HIDIOCGUSAGES来连续接收和发送多个字节,不知道为什么按照此方法写入的指令设备总是不识别?

23,124

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧