1 前言
这几天搞另外一个项目,基于Ubuntu开发一个小的应用程序,就是通过USB HID与设备通信。因此需要在Linux环境编写对应USB HID通信应用。
目前libusb库已经很好的支持USB相关应用的开发,库中提供了丰富的USB接口,用户可以直接调用其提供的API,实现快速开发。
本文对USB HID应用开发进行了简要记录,方便日后自己查看复习。
2 libusb库准备
(1)获取libusb库源码
下面链接是libusb库的源码下载地址。
libusb库源码:https://github.com/libusb/libusb/releases
(2)编译libusb库
获取到源码之后,需要对库进行编译,下面记录了自己编译的指令。
cd libusb-1.0.26/
#配置
./configure --prefix=/home/libusbinstall --build=x86_64-linux --disable-udev
#编译
make
#安装
make install
(3)安装目录
安装之后可以看到目标目录存在两个文件夹:include/ 和 lib/
3 应用示例
下面直接上代码,无需多言,看代码即可(代码风格及规范进行了简化,实际上没那么丑的)。
头文件:hidusb.h
#include <stdint.h>
#include "libusb.h"
int hidUSB_write(libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *pDataIn, int nDataLen, int ntimeout);
int hidUSB_read(libusb_device_handle *dev_handle,unsigned char endpoint, unsigned char *pDataRcv, int nDataLen, int ntimeout);
int hidUSB_open(libusb_device_handle **dev_hdlout, uint16_t vendor_id, uint16_t product_id);
int hidUSB_close(libusb_device_handle *dev_handle);
void hidUSB_DeInit(void);
int hidUSB_Init(void);
源文件:hidusb.c
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "hidusb.h"
static libusb_context *gUSBCtx = NULL;
int hidUSB_write(libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *pDataIn, int nDataLen, int ntimeout)
{
int ret = -1;
int transferred = 0;
ret = libusb_interrupt_transfer(dev_handle, endpoint, pDataIn, nDataLen, &transferred, ntimeout);
if(ret<0){
perror("failed to write\n");
return 0;
}
return transferred;
}
int hidUSB_read(libusb_device_handle *dev_handle,unsigned char endpoint, unsigned char *pDataRcv, int nDataLen, int ntimeout)
{
int ret = -1;
int transferred = 0;
ret = libusb_interrupt_transfer(dev_handle,endpoint, pDataRcv, 64, &transferred, ntimeout);
if(ret!=0){
perror("failed to read\n");
return 0;
}
return transferred;
}
int hidUSB_open(libusb_device_handle **dev_hdlout, uint16_t vendor_id, uint16_t product_id)
{
int ret = -1;
libusb_device_handle *tdev_handle = NULL;
//打开指定pid和vid的设备
tdev_handle = libusb_open_device_with_vid_pid(NULL, vendor_id, product_id);
if(tdev_handle == NULL)
{
perror("Cannot open device\n");
return -1;
}
//内核驱动激活与分离(这一句我没怎么搞懂为啥需要,懂的朋友欢迎留言告诉我)
if(libusb_kernel_driver_active(tdev_handle, 0) == 1)
{
printf("Kernel Driver Active\n");
if(libusb_detach_kernel_driver(tdev_handle, 0) == 0){
printf("Kernel Driver Detached!\n");
}
}
ret = libusb_claim_interface(tdev_handle, 0);
if(ret < 0) {
perror("Cannot Claim Interface\n");
goto iExit;
}
*dev_hdlout = tdev_handle;
return 0;
iExit:
if(tdev_handle)
libusb_close(tdev_handle);
return -1;
}
int hidUSB_close(libusb_device_handle *dev_handle)
{
int ret = -1;
if(dev_handle)
{
ret = libusb_release_interface(dev_handle, 0);
if(ret!=0)
{
perror("Cannot libusb_release_interface\n");
return -1;
}
libusb_close(dev_handle);
}
return 0;
}
void hidUSB_DeInit(void)
{
libusb_exit(gUSBCtx);
}
int hidUSB_Init(void)
{
int ret = -1;
ret = libusb_init(&gUSBCtx);
if(ret < 0)
{
perror("libusb_init failed\n");
return -1;
}
return 0;
}
主程序:main.c
#include <stdio.h>
#include <unistd.h>
#include "hidusb.h"
//设备的标识号
#define HT232_USB_VID 0x5548
#define HT232_USB_PID 0x6666
//这个需要看设备所使用的ep
#define HT232_USB_HID_EPOUT 0x01
#define HT232_USB_HID_EPIN 0x81
int main(void)
{
int ni = 0;
int nRet = -1;
uint8_t ucSndBuf[256] = {0};
uint8_t ucRcvBuf[256] = {0};
uint8_t ucSndLen = 0;
uint8_t ucRcvLen = 0;
libusb_device_handle *dev_handle = NULL;
nRet = hidUSB_Init();
if(nRet != 0)
{
perror("hidUSB_Init failed\r\n");
return -1;
}
nRet = hidUSB_open(&dev_handle, HT232_USB_VID, HT232_USB_PID);
if(nRet != 0)
{
perror("hidUSB_open failed\r\n");
return -1;
}
while(1)
{
ucSndBuf[0] = 0x01;
ucSndBuf[1] = 0x02;
ucSndBuf[2] = 0x03;
ucSndBuf[3] = 0x04;
ucSndLen = 4;
nRet = hidUSB_write(dev_handle, HT232_USB_HID_EPOUT, ucSndBuf, ucSndLen, 1000);
if(nRet == 0)
{
perror("hidUSB_write failed\r\n");
goto iSleep;
}
ucRcvLen = hidUSB_read(dev_handle, HT232_USB_HID_EPIN, ucRcvBuf, sizeof(ucRcvBuf), 1000);
if(ucRcvLen == 0)
{
perror("hidUSB_read failed\r\n");
goto iSleep;
}
for(ni=0; ni<ucRcvLen; ni++)
{
printf("%02X ", ucRcvBuf[ni]);
}
printf("\r\n");
iSleep:
sleep(1);
}
nRet = hidUSB_close(dev_handle);
if(nRet != 0)
{
perror("hidUSB_open failed\r\n");
}
hidUSB_DeInit();
return 0;
}
上述即为Linux环境下USB HID应用编程demo。
4 结束语
知识分享,共同进步。
over!
--------------------------------------------------------------------------------------------------------------
卖个广告:ble、4G、lora、wifi等门禁设备,各种读卡器模块、成品都有,若有需要,可私信。