libusb 介紹
libusb是開源的C庫,使用該庫是的用戶可以在應用程序中直接訪問 USB 設備,無需為 USB 設備編寫內核驅動。libusb支持多個平臺 (linux, window, ios),所以可以很方便地將應用程序移植到其他平臺。
linux libusb 安裝
從網上下載libusb的源碼,下載地址:http://www.libusb.org/, 下載后編譯安裝。
# tar jxvf libusb-1.0.20.tar.bz2
# cd libusb-1.0.20
# ./configure
# make
# sudo make install
ubuntu下可以通過以下命令快速安裝。
sudo apt-get isntall libusb*
安裝后,libusb的頭文件被安裝在/usr/local/include/libusb-1.0 ,鏈接庫被安裝在/usr/loacal/lib目錄下。
usb bulk 傳輸例程
這個例程演示如何使用 libusb 庫,編寫 USB bulk xfer 上位機demo,可以正常接收和發送數據。注意,修改程序中的 VID 和 PID 的值和你 device 板子上所定義的一致,傳輸數據塊的大小不要超過 device 定義的最大傳輸長度。
#include
#include
#include
#include
#include "libusb.h"
#define VID 0x8888
#define PID 0x0088
#define edp2in 0x82
#define edp2out 0x02
int main(void)
{
libusb_device **devs, *dev;
int ret, i;
ssize_t cnt;
usb_pro_t usb_pro;
struct libusb_device_handle *handle = NULL;
libusb_context *ctx = NULL;
ret = libusb_init(&ctx);
if (ret < 0)
return -1;
libusb_set_debug(ctx, 3);
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0) {
printf("no usb dev on bus\r\n");
return -1;
}
i = 0;
while((dev = devs[i++]) != NULL) {
ret = libusb_get_device_descriptor(dev,&desc);
if (ret < 0) {
printf("failed to get device descriptor");
goto error;
}
if ((desc.idVendor == VID) && (desc.idProduct == PID)) {
printf("bLength: 0x%04x\r\n", desc.bLength);
printf("bDescriptorType: 0x%04x\r\n", desc.bDescriptorType);
printf("bcdUSB: 0x%04x\r\n", desc.bcdUSB);
printf("bDeviceClass: 0x%04x\r\n", desc.bDeviceClass);
printf("bDeviceSubClass: 0x%04x\r\n", desc.bDeviceSubClass);
printf("bDeviceProtocol: 0x%04x\r\n", desc.bDeviceProtocol);
printf("bMaxPacketSize0: 0x%04x\r\n", desc.bMaxPacketSize0);
printf("vendor id: 0x%04x\r\n", desc.idVendor);
printf("product id: 0x%04x\r\n", desc.idProduct);
printf("bcdDevice: 0x%04x\r\n", desc.bcdDevice);
printf("iManufacturer: 0x%04x\r\n", desc.iManufacturer);
printf("iProduct: 0x%04x\r\n", desc.iProduct);
printf("iSerialNumber: 0x%04x\r\n", desc.iSerialNumber);
printf("bNumConfigurations: 0x%04x\r\n", desc.bNumConfigurations);
}
}
handle = libusb_open_device_with_vid_pid(ctx, VID, PID);
if (handle == NULL) {
printf("cant't open device\r\n");
goto error;
} else {
printf("open device\r\n");
}
libusb_free_device_list(devs, 1);
if (libusb_kernel_driver_active(handle, 0) ==1) {
printf("kernel driver active, detach it \r\n");
if (libusb_detach_kernel_driver(handle, 0) == 0) {
printf("detached kernel driver\r\n");
}
else {
goto error;
}
}
ret = libusb_claim_interface(handle, 0);
if (ret < 0) {
printf("can't claim interface\r\n");
goto error;
} else {
printf("claimed interface\r\n");
}
char data[64];
int actual_len = 0;
int didi = 1000;
for (int i = 0; i< 1000; i++) {
memset(data, 0, sizeof(data));
/* receive data from device */
/*
ret = libusb_bulk_transfer(handle, edp2in, data, 64, &actual_len, 0);
if (actual_len = 0) {
printf("received nothing\r\n");
} else {
printf("bulk transfer: %s\r\n", data);
}
usleep(200000);
*/
char *str = "am host";
sprintf(data, "am host %d\r\n", i);
ret = libusb_bulk_transfer(handle, edp2out, data, strlen(data), &actual_len, 0);
if (actual_len != 0) {
printf("send data: %s\r\n", data);
}
usleep(200000);
}
libusb_close(handle);
error:
printf("free device list\r\n");
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
return 0;
}
編譯
編譯代碼可以使用 makefile 文件,也可以是使用命令行命令編譯,這里給出兩種編譯方法。
makefile
CC = gcc
# your libusb library path, be careful your path.
LDIR = /usr/loacal/lib
# link flag
LFLAG = -lusb-1.0
# libusb hearder file path
INCLUDES = /usr/local/include/libusb-1.0
CFLAGS = -I$(INCLUDES) -std=c99
src = $(wildcard *.c)
obj = $(patsubst %.c, %.o, $(src))
.PHONY: all clean
all: main
main: $(obj)
$(CC) $(obj) -o main -L$(LDIR) $(LFLAG)
%.o:%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
@-rm -f main $(obj)
命令行編譯
命令中-I/usr/local/include/libusb-1.0 告訴編譯器 libusb 的頭文件所在的路徑。-L/usr/local/lib/ 告訴鏈接器所要鏈接的庫文件路徑。-lusb-1.0 告訴編譯器需要鏈接 libusb-1.0.so這個庫。
gcc -I/usr/local/include/libusb-1.0 -std=c99 main.c -o main -L/usr/local/lib/ -lusb-1.0
運行
編譯后會在當前目錄下生成一個名叫“main“的可執行文件,運行這個文件。如果打開USB設備時出錯提示permission error,那么使用
# sudo ./main
運行后,HOST每隔200ms 向 device 發送一個數據包。
源碼下載
我的源碼已上傳到http://download.csdn.net/detail/chengwenyang/9479835 ,包含STM32F4Discovery板子的 usb bulk 傳輸的工程文件和 使用 libusb 編寫的上位機程序。
上一篇:STM32F4中USB與PC雙向通信
下一篇:使用stm32F10XX芯片開發的USB HID 雙向通信
推薦閱讀
史海拾趣
2016年,B+B SmartWorx與研華達成合并協議,成為研華全球大家庭的一員。這次合并是雙方戰略發展的重要一步,研華看中了B+B SmartWorx在物聯網和工業網通領域的深厚積累,而B+B SmartWorx則借助研華在亞洲的資源與經驗,進一步拓展其全球市場。合并后,雙方在產品開發、業務布局等方面進行了深度融合,共同推動工業物聯網領域的發展。
在電子行業快速發展的同時,AE公司也面臨著來自市場競爭、技術更新等多方面的挑戰。然而,AE公司憑借其敏銳的市場洞察力和強大的研發實力,成功應對了這些挑戰。公司不斷調整戰略方向,優化產品結構,提升服務質量,以適應市場的變化。同時,AE公司也積極關注未來技術的發展趨勢,加大在新興領域的投入,為公司的未來發展奠定了堅實的基礎。
以上只是AE公司在電子行業中的部分發展故事概述,每個故事都體現了AE公司在技術創新、市場拓展、合作伙伴關系等方面的努力和成就。這些故事不僅展示了AE公司的成長歷程,也反映了整個電子行業的發展變遷。
FINISAR在光模塊領域取得了多項重要技術創新和突破。例如,公司在1992年推出了首個850nm的千兆多模光纖光收發模塊,隨后在1995年推出了帶數字診斷功能的光收發模塊,這些創新產品極大地推動了光通信技術的發展。此外,FINISAR還不斷推出新產品以滿足市場需求,如SFP光模塊、CWDM GBIC光模塊等,這些產品均獲得了市場的廣泛認可。
FINISAR公司(前身為Finisar Corporation)成立于1987年(另有資料稱成立于1988年),總部位于美國加利福尼亞州的硅谷地區。公司自創立之初便專注于光通信技術的研發與應用,致力于設計、制造和銷售高性能的光模塊和光網絡設備。在成立初期,FINISAR憑借其創新的技術和高質量的產品,在光通信市場上逐漸嶄露頭角,為后續的快速發展奠定了堅實基礎。
面對全球市場的競爭壓力,EAO公司堅定實施全球化戰略。公司在全球范圍內建立了完善的銷售網絡和售后服務體系,為客戶提供及時、高效的服務。同時,EAO公司還積極尋求與國際知名企業的合作機會,共同開拓市場、分享資源。通過全球化戰略的實施,EAO公司不斷提升品牌影響力和市場競爭力。
面對全球市場的競爭壓力,EAO公司堅定實施全球化戰略。公司在全球范圍內建立了完善的銷售網絡和售后服務體系,為客戶提供及時、高效的服務。同時,EAO公司還積極尋求與國際知名企業的合作機會,共同開拓市場、分享資源。通過全球化戰略的實施,EAO公司不斷提升品牌影響力和市場競爭力。
EPS主要由[url=http://www.ftxsensor.cn/]扭矩傳感器[/url]、車速傳感器、電動機、減速機構和電子控制單元(ECU)等組成。 通過傳感器探測司機在轉向操作時方向盤產 ...… 查看全部問答∨ |
|
1 引言 生化反應池在水處理過程中非常重要。需要通過調整風機的轉速控制反應池中的DO值。理論上應該通過調節電動機的轉速來實現,但實際上卻是利用擋板閥門后者放空的方法進行調節。這種方法極大地浪費了電力資源。以美國TI公司推出的TMS320LF240 ...… 查看全部問答∨ |
|
我想在一個多任務程序中用udp方式實現任務之間的通信,應該屬于在本地機上實現通信,不知道怎么做啊,把ip設成一樣的127.0.0.1就可以了嗎?… 查看全部問答∨ |
1,請教幾個問題,是不是理論上來說,任何linux版本都可以移植到2440上,只是易難不同? 2.如果2440移植的不是三星提供的版本,那是不是移植非常困難,但是據我所知三星只提供mizi版呀?而mizi是面對2410的呀?貴公司在2440的板子上移植Linux 2.6.1 ...… 查看全部問答∨ |
我想在ADS下調用libxml2解析器的函數,有知道怎么導入的么? 或者還有其他更方便的xml解析庫么? 剛用tinyxml試了下,好多Error,是不是ADS下對c++支持不怎么好?… 查看全部問答∨ |
|