linux下 libusb使用--開啟usb裝置進行通訊
下載編譯安裝libusb:https://blog.csdn.net/u011598479/article/details/82705378
1.確定你要通訊的USB裝置的一些引數。
user_device.idProduct = USB_PRODUCT_ID; //PID
user_device.idVendor = USB_VENDOR_ID ; //VID
user_device.bInterfaceClass = LIBUSB_CLASS_PRINTER ; //印表機裝置
user_device.bInterfaceSubClass = LIBUSB_CLASS_PER_INTERFACE ; //預留介面
user_device.bmAttributes = LIBUSB_TRANSFER_TYPE_BULK ; //usb bulk 通訊方式
user_device.dev = NULL; //初始化引數
user_device為我設定的結構體,用來儲存一些要用到的引數。
2.init_libusb(); //呼叫這個庫函式初始化庫
3.獲取裝置描述符,然後根據第一步的裝置引數遍歷配置描述符,介面描述符,端點描述符,找到USB裝置端點地址
4.開啟裝置libusb_open_device_with_vid_pid()
5.宣告介面libusb_claim_interface()
6.傳送資料libusb_bulk_transfer()
7.關閉裝置,釋放介面,釋放申請的空間,退出庫
libusb_close(g_usb_handle);
libusb_release_interface(g_usb_handle,user_device.bInterfaceNumber);
libusb_free_device_list(user_device.devs, 1);
libusb_exit(NULL);
# C compiler options
CC = gcc
#CFLAGS = -g -O2
TARGET = main
LIBSPATH = ../lib
PLATFORM = linux32
#LIBS = /usr/local/lib -lusb-1.0
LIBS = /usr/local/lib/libusb-1.0.a -lm -lpthread
INC = /usr/local/include/libusb-1.0
#多位元組字元 指定漢字編碼方式GB18030
EXCHAR = -fexec-charset=GB18030
# Source files
SRCS = main.c
# Object files
OBJS = $(SRCS:.c=.o)
# Make everything
all: $(TARGET)
# Make the application
#-lstdc++:編譯c++的時候用到
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $(EXCHAR) -o $(TARGET) $(OBJS) $(LIBS)
# Dependencies
#$@:表示目標檔案,即:demo.o
#$<:表示依賴檔案,即:demo.c
#-I$(INC) :指向包含了的.h檔案的路徑 即wbe,h的路徑
$(OBJS): %.o: %.c
$(CC) -c $(CFLAGS) $(EXCHAR) -o $@ $< -I$(INC)
#
# Clean all object files...
#
clean:
$(RM) $(OBJS) $(TARGET)
/*
* libusb example program to list devices on the bus
* Copyright © 2007 Daniel Drake <dsd@gentoo.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include "libusb.h"
#define USB_VENDOR_ID 0x0483
#define USB_PRODUCT_ID 0x8007
#define BULK_ENDPOINT_OUT 1
#define BULK_ENDPOINT_IN 2
struct userDevice{
/*Device descriptor*/
/** USB-IF vendor ID */
uint16_t idVendor;
/** USB-IF product ID */
uint16_t idProduct;
/*Interface descriptor*/
/** USB-IF class code for this interface. See \ref libusb_class_code. */
uint8_t bInterfaceClass;
/** USB-IF subclass code for this interface, qualified by the
* bInterfaceClass value */
uint8_t bInterfaceSubClass;
/*Endpoint descriptor*/
/** Attributes which apply to the endpoint when it is configured using
* the bConfigurationValue. Bits 0:1 determine the transfer type and
* correspond to \ref libusb_transfer_type. Bits 2:3 are only used for
* isochronous endpoints and correspond to \ref libusb_iso_sync_type.
* Bits 4:5 are also only used for isochronous endpoints and correspond to
* \ref libusb_iso_usage_type. Bits 6:7 are reserved.
*/
uint8_t bmAttributes;
/*save parameter*/
libusb_device *dev;
libusb_device **devs;
u_int8_t bInEndpointAddress;
u_int8_t bOutEndpointAddress;
/* Number of this interface */
uint8_t bInterfaceNumber;
};
int init_libusb(void)
{
/*1. init libusb lib*/
int rv = 0;
rv = libusb_init(NULL);
if(rv < 0) {
printf("*** initial USB lib failed! \n");
return -1;
}
return rv;
}
int get_device_descriptor(struct libusb_device_descriptor *dev_desc,struct userDevice *user_device)
{
/*2.get device descriptor*/
int rv = -2;
ssize_t cnt;
int i = 0;
libusb_device **devs;
libusb_device *dev;
cnt = libusb_get_device_list(NULL, &devs); //check the device number
if (cnt < 0)
return (int) cnt;
while ((dev = devs[i++]) != NULL) {
rv = libusb_get_device_descriptor(dev,dev_desc);
if(rv < 0) {
printf("*** libusb_get_device_descriptor failed! i:%d \n",i);
return -1;
}
if(dev_desc->idProduct==user_device->idProduct &&dev_desc->idVendor==user_device->idVendor)
{
user_device->dev = dev;
user_device->devs = devs;
rv = 0;
break;
}
}
return rv;
}
int match_with_endpoint(const struct libusb_interface_descriptor * interface, struct userDevice *user_device)
{
int i;
int ret=0;
for(i=0;i<interface->bNumEndpoints;i++)
{
if((interface->endpoint[i].bmAttributes&0x03)==user_device->bmAttributes) //transfer type :bulk ,control, interrupt
{
if(interface->endpoint[i].bEndpointAddress&0x80) //out endpoint & in endpoint
{
ret|=1;
user_device->bInEndpointAddress = interface->endpoint[i].bEndpointAddress;
}
else
{
ret|=2;
user_device->bOutEndpointAddress = interface->endpoint[i].bEndpointAddress;
}
}
}
if(ret==3)
{
return 1;
}
else
{
return 0;
}
}
int get_device_endpoint(struct libusb_device_descriptor *dev_desc,struct userDevice *user_device)
{
/*3.get device endpoint that you need */
int rv = -2;
int i,j,k;
struct libusb_config_descriptor *conf_desc;
u_int8_t isFind = 0;
for (i=0; i< dev_desc->bNumConfigurations; i++)
{
if(user_device->dev != NULL)
rv = libusb_get_config_descriptor(user_device->dev,i,&conf_desc);
if(rv < 0) {
printf("*** libusb_get_config_descriptor failed! \n");
return -1;
}
for (j=0; j< conf_desc->bNumInterfaces; j++)
{
for (k=0; k < conf_desc->interface[j].num_altsetting; k++)
{
if(
conf_desc->interface[j].altsetting[k].bInterfaceClass==user_device->bInterfaceClass
)
{
if(match_with_endpoint(&(conf_desc->interface[j].altsetting[k] ), user_device ))
{
user_device->bInterfaceNumber = conf_desc->interface[j].altsetting[k].bInterfaceNumber;
libusb_free_config_descriptor(conf_desc);
rv = 0;
return rv;
}
}
}
}
}
return -2; //don't find user device
}
int main(void)
{
int rv;
int length;
unsigned char a[100] = {0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a};
libusb_device_handle* g_usb_handle;
struct userDevice user_device;
struct libusb_device_descriptor dev_desc;
user_device.idProduct = USB_PRODUCT_ID;
user_device.idVendor = USB_VENDOR_ID ;
user_device.bInterfaceClass = LIBUSB_CLASS_PRINTER ;
user_device.bInterfaceSubClass = LIBUSB_CLASS_PRINTER ;
user_device.bmAttributes = LIBUSB_TRANSFER_TYPE_BULK ;
user_device.dev = NULL;
init_libusb();
rv = get_device_descriptor(&dev_desc,&user_device);
if(rv < 0) {
printf("*** get_device_descriptor failed! \n");
return -1;
}
rv = get_device_endpoint(&dev_desc,&user_device);
if(rv < 0) {
printf("*** get_device_endpoint failed! rv:%d \n",rv);
return -1;
}
/*4.open device and start communication by usb*/
//open the usb device
g_usb_handle = libusb_open_device_with_vid_pid(NULL, user_device.idVendor, user_device.idProduct);
if(g_usb_handle == NULL) {
printf("*** Permission denied or Can not find the USB board (Maybe the USB driver has not been installed correctly), quit!\n");
return -1;
}
rv = libusb_claim_interface(g_usb_handle,user_device.bInterfaceNumber);
if(rv < 0) {
rv = libusb_detach_kernel_driver(g_usb_handle,user_device.bInterfaceNumber);
if(rv < 0) {
printf("*** libusb_detach_kernel_driver failed! rv%d\n",rv);
return -1;
}
rv = libusb_claim_interface(g_usb_handle,user_device.bInterfaceNumber);
if(rv < 0)
{
printf("*** libusb_claim_interface failed! rv%d\n",rv);
return -1;
}
}
rv = libusb_bulk_transfer(g_usb_handle,BULK_ENDPOINT_OUT,a,100,&length,1000);
if(rv < 0) {
printf("*** bulk_transfer failed! \n");
return -1;
}
libusb_close(g_usb_handle);
libusb_release_interface(g_usb_handle,user_device.bInterfaceNumber);
libusb_free_device_list(user_device.devs, 1);
libusb_exit(NULL);
}
相關文章
- USB共享網路:android手機通過USB與Ubuntu進行socket網路通訊AndroidUbuntu
- linux模擬HID USB裝置及wireshark USB抓包配置Linux
- 使用 Linux 命令列與其他使用者進行通訊Linux命令列
- 痞子衡嵌入式:可通過USB Device Path來唯一指定i.MXRT裝置進行ROM/Flashloader通訊dev
- 【USB】C#使用HID通訊C#
- C#如何開發透過USB進行串列埠通訊的Androud上位機C#串列埠
- Linux應用可通過USB訪問Android裝置-Chrome OS 75版釋出LinuxAndroidChrome
- (16)USB通訊
- Qt usb通訊QT
- win10禁用所有usb儲存裝置方法 win10如何禁止使用usb儲存裝置Win10
- 使用SuperSocket的FixedHeaderReceiveFilter進行通訊HeaderFilter
- Halo 正式開源: 使用可穿戴裝置進行開源健康追蹤
- 樂訊通雲通訊:物聯網路卡在什麼裝置上使用
- Linux 下使用 NetLink 檢測裝置的熱插拔Linux
- 使用UDP如何進行網路通訊UDP
- C++使用libcurl進行http通訊C++HTTP
- HarmonyOS 裝置管理開發:USB 服務開發指導
- Linux單裝置多路USB串列埠的實現方法介紹Linux串列埠
- Linux下Nginx安裝並開啟SSLLinuxNginx
- 在 Laravel 中使用 Workerman 進行 socket 通訊Laravel
- 使用Google Protocol Bufffers進行通訊(Ruby & C)GoProtocol
- C# 使用SuperSocket的FixedHeaderReceiveFilter進行通訊C#HeaderFilter
- USB裝置遠端喚醒RemoteWakeUpREM
- Windows10usb裝置正在使用中無法彈出Windows
- 通過串列埠進行通訊 :串列埠
- 使用 Frida 逆向分析 Android 應用與 BLE 裝置的通訊Android
- Android Socket連線,使用Socket進行通訊(Android)Android
- lsusb命令-在系統中顯示有關USB裝置資訊
- 【轉載】WSL 如何連線USB裝置
- USB之裝置插入波形變化2
- Linux 下的程式間通訊:使用管道和訊息佇列Linux佇列
- 使用網雲穿內網穿透設定逆向usb裝置共享內網穿透
- BootISO:從 ISO 檔案中建立一個可啟動的 USB 裝置boot
- Linux開發板(樹莓派)和伺服器進行雙向通訊(socket)Linux樹莓派伺服器
- 華為通訊裝置密碼設定密碼
- 無法識別usb裝置怎麼辦_win10無法識別usb裝置的解決方法Win10
- 使用4G通訊模組和MQTT協議,完成物聯網裝置開發。MQQT協議
- Windows 11 可以透過組策略來禁止使用USB儲存裝置。Windows