RK35XX 嵌入式linux移植usblib
一、什么是libusb
libusb 是一個開源的、跨平臺的用戶態 USB 設備訪問庫,允許應用程序直接與 USB 設備通信,無需依賴內核驅動。
這對于開發者簡化了對于復雜的USB驅動的編寫。而且可移植性非常好,不會出現我在A內核版本設備下編譯的驅動,拿到B內核版本設備下不能運行的問題。
二、libusb的開發形式
libusb支持多平臺,包括但不限于linux(arm+x86)、Windows、Android等。
libusb以源碼形式開源,通過編譯平臺的編譯鏈工具對源碼進行編譯生成靜態鏈接庫,拿到靜態鏈接庫就可以開發自己的應用了。
下面以嵌入式linux平臺(RK35XX)為例介紹移植、使用過程.
二、如何在嵌入式linux設備上移植libusb
1.源碼獲取
libusb的源碼托管在GitHub上,鏈接地址如下:
[https://github.com/libusb/libusb/releases]
選擇一個版本的tar.bz2壓縮文件即可,

2.源碼編譯
1. 將源碼拷貝到編譯環境中,進行解壓:
sudo tar -xjf libusb-1.0.23.tar.bz2
解壓后,進入文件目錄,目錄下文件結構如下:

這里重點部分來了!!!選擇我們目標運行平臺的交叉編譯鏈工具,比如RK平臺的交叉編譯鏈工具為:aarch64-linux-gnu
一定需要確保你的編譯平臺已經正確安裝了該交叉編譯鏈工具,在shell中輸入aarch幾個關鍵字后TAB鍵可以自動補全就說明已經安裝好交叉編譯鏈工具了。
2.接下來,我們生成Makefile
在根目錄下輸入以下命令:
./configure --host=aarch64-linux-gnu --disable-udev --prefix=/home/.../libusb_install
其中:
--host 參數后面跟的指定交叉編譯鏈工具前綴,這里我們選擇的是aarch64-linux-gnu
--disable-udev 是關閉udev編譯,有些編譯環境沒有該庫,會導致報錯
--prefix 參數后面跟的是靜態鏈接庫的安裝位置,默認的話放在/usr/lib目錄下了,需要注意的是,該目錄一定需要存在,且為空目錄,否則后面的make install會失敗。
3. 編譯
在源碼根目錄下執行以下命令:
sudo make
4. 安裝
在源碼根目錄下執行以下命令:
make install
如果沒有報錯,會在你的安裝目錄下生成include、lib兩個目錄,
其中include里,存放了usblib的頭文件,lib目錄下存放了靜態鏈接庫。結構如下:

判斷以下靜態庫的架構:
file /home/.../usb_lib_installed/lib/libusb-1.0.so.0.2.0
結果應該輸出為:
ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=007c750c75544f910a8fb574b6231d19ab69ee79, with debug_info, not stripped
至此,我們就完成了RK平臺的usblib的編譯過程,我們就可以用靜態鏈接庫和頭文件去開發自己的應用了。
3. usblib的開發
這里我們就以獲取usb設備列表并打印為例,說明usblib庫的使用及編譯。
1. 測試代碼:
點擊查看代碼
#include <stdio.h>
#include <stdlib.h>
#include "libusb.h"
int main() {
libusb_context *ctx = NULL;
libusb_device **devs;
ssize_t cnt;
// 初始化libusb
if (libusb_init(&ctx) < 0) {
fprintf(stderr, "Failed to initialize libusb\n");
return 1;
}
// 獲取設備列表
cnt = libusb_get_device_list(ctx, &devs);
if (cnt < 0) {
fprintf(stderr, "Failed to get device list\n");
libusb_exit(ctx);
return 1;
}
// 打印設備信息
for (ssize_t i = 0; i < cnt; ++i) {
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(devs[i], &desc) == 0) {
printf("Device %d: VendorID=%04x ProductID=%04x\n", (int)i, desc.idVendor, desc.idProduct);
}
}
// 釋放設備列表
libusb_free_device_list(devs, 1);
// 清理libusb
libusb_exit(ctx);
return 0;
}
2. 編譯APP
使用RK35XX平臺的交叉編譯鏈工具對我們的APP進行編譯:
aarch64-linux-gnu-gcc usb_wr_test.c -o usb_wr_testAPP -L./usb_lib_1.0.0.23_install/lib/ -lusb-1.0 -I./usb_lib_1.0.0.23_install/include/libusb-1.0.so.0.2.0
-L 參數路徑必須包含 libusb-1.0.so 或 libusb-1.0.so.0。
-I 參數路徑必須包含 libusb.h(路徑末尾的 libusb-1.0 是必須的)。
如果編譯失敗,請檢查-L 和-I的目錄是否為usblib的安裝目錄。
若提示找不到lusb-1.0,請檢查靜態鏈接庫的架構,是否為 arm 64bit
判斷以下靜態庫的架構:
file /home/.../usb_lib_installed/lib/libusb-1.0.so.0.2.0
編譯成功后,會在本目錄下生成usb_wr_testAPP 的目標文件,我們通過ADB、SSH等方式拷貝至目標板卡中。
3. 運行
通過串口、adb等方式登錄到RK板卡中后,給usb_wr_testAPP 賦予可執行權限:
chmod +x usb_wr_testAPP
隨后,插入一個USB設備,運行APP:
./usb_wr_testAPP
現象應該如下:


浙公網安備 33010602011771號