您现在的位置是:首页 >其他 >imx6ull开发板环境配置 - libusb、libudev、eudev交叉编译网站首页其他

imx6ull开发板环境配置 - libusb、libudev、eudev交叉编译

_Herc 2023-06-26 16:00:02
简介imx6ull开发板环境配置 - libusb、libudev、eudev交叉编译

目录

零、前言

一、libusb交叉编译

1.0 前言

1.1 交叉编译

二、usbutils交叉编译

2.0 前言

2.1 交叉编译

三、libudev交叉编译

3.0 前言

3.1 交叉编译

3.2 错误处理-没找到usbutils

3.3 错误处理-没找到pci.ids (pci.ids not found)

3.3.0 前言

3.3.1 查找pci.ids

3.3.2 继续编译

3.4 错误处理-没找到gperf (gperf not found)

 3.5 编译并安装

四、eudev交叉编译

4.0 前言

4.1 交叉编译

五、测试代码

5.1 usb测试代码

5.2 编译脚本Makefile

5.3 运行结果


零、前言

背景:由于正点原子imx6ull需要使用到usblib进行一些usb相关的编程,而正点没有提供对应的usblib相关的库交叉编译方法。下面简单介绍如何交叉编译usb开发所需要的库。
依赖关系:libusb<-usbutils<-libudev   交叉编译建议按照下面的顺序进行,防止出现冲突
现象:使用测试代码进行编译,出现如下错误,原因是缺少对应的 libusb、libudev库
alientek@ubuntu16:~/linuxProject/v4l2_test/usb_callback_test$ make
arm-linux-gnueabihf-gcc  -o usb_callback_test usb_callback_test.c -lpthread -lusb-1.0 -I/home/alientek/tools/libusb-1.0.26/build/include -L/home/alientek/tools/libusb-1.0.26/build/lib
/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/bin/ld: warning: libudev.so.1, needed by /home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so, not found (try using -rpath or -rpath-link)
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_monitor_filter_add_match_subsystem_devtype@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_monitor_enable_receiving@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_enumerate_scan_devices@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_new@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_device_get_devnode@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_enumerate_new@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_list_entry_get_name@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_enumerate_add_match_subsystem@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_device_get_sysname@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_enumerate_get_list_entry@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_enumerate_add_match_property@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_device_new_from_syspath@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_monitor_new_from_netlink@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_monitor_receive_device@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_device_unref@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_enumerate_unref@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_monitor_get_fd@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_list_entry_get_next@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_monitor_unref@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_unref@LIBUDEV_183’未定义的引用
/home/alientek/tools/libusb-1.0.26/build/lib/libusb-1.0.so:对‘udev_device_get_action@LIBUDEV_183’未定义的引用
collect2: error: ld returned 1 exit status
Makefile:9: recipe for target 'usb_callback_test' failed
make: *** [usb_callback_test] Error 1

 

一、libusb交叉编译

1.0 前言

参考:韦东山驱动大全-12USB-07_使用libusb读取鼠标参数
库版本:libusb-1.0.26(https://sourceforge.net/projects/libusb/)

1.1 交叉编译

sudo apt-get install libtool

unzip libusb-1.0.26.zip
cd libusb-1.0.26
mkdir build
./autogen.sh

./configure CC={编译器目录} --host=arm-linux-gnueabihf --prefix=$PWD/build

make

make install        #安装在build目录下

编译时需要指定头文件路径/home/alientek/tools/libusb-1.0.26/build/include

库文件路径/home/alientek/tools/libusb-1.0.26/build/lib

二、usbutils交叉编译

2.0 前言

2.1 交叉编译

#unzip
cd usbutils-005
mkdir build
./configure CC={编译器目录} --host=arm-linux-gnueabihf --prefix=$PWD/build
make
make install

三、libudev交叉编译

3.0 前言

库版本: udev-182

3.1 交叉编译

#unzip
cd udev-182
mkdir build
./configure CC={编译器目录} --host=arm-linux-gnueabihf --prefix=$PWD/build
make
make install

环境没有问题的话,能够一次编译成功,如下所示。但实际上会缺少部分文件,详情根据3.2以后章节查看。

 

3.2 错误处理-没找到usbutils

如果configure配置失败,出现没找到usbutils错误,需要检查是否usbutils安装出现问题

 通过查看上面打印信息可以看到使用的pkg-config路径为/opt/fsl-imx-x11/4.1.15-2.1.0/目录下。通过下面指令找到实际存放的pkgconfig路径

cd /opt/fsl-imx-x11/4.1.15-2.1.0/            #根据提示信息自行修改
find ./ -name "pkgconfig"                                         #得到路径/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/lib/pkgconfig

将usbutils-005目录下交叉编译生成的文件放到上述pkgconfig目录下

cp {usbutils-005}/build/share/pkgconfig/usbutils.pc  /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/lib/pkgconfig

完成上述操作后,再次配置udev-182

./configure  --host=arm-linux-gnueabihf --prefix=$PWD/build            #配置udev交叉编译

提示如下错误:

 

3.3 错误处理-没找到pci.ids (pci.ids not found)

3.3.0 前言

参考: 交叉编译 udev 库_pci.ids not found_huihuiwith的博客-CSDN博客

3.3.1 查找pci.ids

    使用参考连接中的whereis pci.ids无法找到有效地址。这里使用find指令查找:sudo find / -name "pci.ids"

    找到两个路径。疑问:我们需要是的交叉编译,可以直接只是x86的ids吗?

3.3.2 继续编译

    指定pci路径地址,再次配置

./configure  --host=arm-linux-gnueabihf --prefix=$PWD/build --with-pci-ids-path=/usr/share/misc/pci.ids

提示gperf not found

3.4 错误处理-没找到gperf (gperf not found)

参考: configure: error: gperf is needed_tool gperf is required._柳鲲鹏的博客-CSDN博客

通过apt安装gperf: 

sudo apt install gperf

再次配置即可成功

 3.5 编译并安装

make 
make install

注:本人在进行make过程中,出现了/bin/grep: /usr/lib/libglib-2.0.la: No such file or director等问题。根据其他人的博文内容,udev已经很久没有更新,而且也有eudev作为更好的替代品。因此后面修改使用eudev进行交叉编译。

四、eudev交叉编译

4.0 前言

参考海思Hi3536交叉编译eudev和libusb库_eudev 3.2.9编译_mkelehk的博客-CSDN博客

eudev版本:3.2.11  ( Archived eudev tarballs (gentoo.org)

4.1 交叉编译

sudo apt install gperf
#解压
cd eudev-3.2.11
mkdir build
./configure  --host=arm-linux-gnueabihf --prefix=$PWD/build --disable-blkid --disable-kmod
make
make install

将交叉编译的头文件、动态库文件放到交叉工具链中

cd {eudev目录}/build
cp bin/udevadm ~/linux/nfs/rootfs-alientek/bin/

sudo cp lib/* /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/lib/

sudo cp include/* /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/include/

五、测试代码

5.1 usb测试代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libudev.h>
#include <sys/select.h>

// 打印设备信息
void print_device_info(struct udev_device *dev) {
    // 获取设备信息
    const char *devpath   = udev_device_get_devpath(dev);
    const char *subsystem = udev_device_get_subsystem(dev);
    const char *devtype   = udev_device_get_devtype(dev);
    const char *syspath   = udev_device_get_syspath(dev);
    const char *sysname   = udev_device_get_sysname(dev);
    const char *sysnum    = udev_device_get_sysnum(dev);
    const char *devnode   = udev_device_get_devnode(dev);
   

    // 打印设备信息
    printf("Device info:
");
    printf("  devpath   : %s
", devpath  );
    printf("  subsystem : %s
", subsystem);
    printf("  devtype   : %s
", devtype  );
    printf("  syspath   : %s
", syspath  );
    printf("  sysname   : %s
", sysname  );
    printf("  sysnum    : %s
", sysnum   );
    printf("  devnode   : %s
", devnode  );
    printf("
");
}

// 遍历USB设备
void enumerate_usb_devices(struct udev *udev) {
    // 创建枚举器
    struct udev_enumerate *enumerate = udev_enumerate_new(udev);
    // 设置匹配条件
    udev_enumerate_add_match_subsystem(enumerate, "usb");
    // 扫描设备
    udev_enumerate_scan_devices(enumerate);

    // 获取设备列表
    struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
    struct udev_list_entry *dev_list_entry;

    // 遍历设备列表
    udev_list_entry_foreach(dev_list_entry, devices) {
        // 获取设备路径
        const char *path = udev_list_entry_get_name(dev_list_entry);
        // 创建设备对象
        struct udev_device *dev = udev_device_new_from_syspath(udev, path);

        if (dev) {
            // 打印设备信息
            print_device_info(dev);
            // 释放设备对象
            udev_device_unref(dev);
        }
    }

    // 释放枚举器
    udev_enumerate_unref(enumerate);
}


int main() {
    // 创建一个udev对象
    struct udev *udev = udev_new();

    if (!udev) {
        // 创建失败
        fprintf(stderr, "Failed to create udev context
");
        return 1;
    }

    // 枚举所有USB设备并打印它们的信息
    enumerate_usb_devices(udev);

    // 创建udev monitor对象,并设置要监听的设备类型为usb
    struct udev_monitor *monitor = udev_monitor_new_from_netlink(udev, "udev");
    udev_monitor_filter_add_match_subsystem_devtype(monitor, "usb", NULL);

    // 启用udev monitor接收事件
    udev_monitor_enable_receiving(monitor);

    // 获取monitor的文件描述符
    int fd = udev_monitor_get_fd(monitor);
    fd_set fds;

    // 进入循环,等待事件发生
    while (1) {
        // 清空文件描述符集合并将monitor的文件描述符添加到集合中
        FD_ZERO(&fds);
        FD_SET(fd, &fds);

        // 调用select函数等待文件描述符就绪
        int ret = select(fd + 1, &fds, NULL, NULL, NULL);

        if (ret > 0 && FD_ISSET(fd, &fds)) {
            // 从monitor中接收一个事件对象
            struct udev_device *dev = udev_monitor_receive_device(monitor);

            if (dev) {
                // 获取事件动作(add或remove)
                const char *action = udev_device_get_action(dev);

                if (strcmp(action, "add") == 0) {
                    // 如果是add事件,打印提示信息并枚举所有USB设备
                    printf("USB device added
");
                    // enumerate_usb_devices(udev);
                }
                else if (strcmp(action, "remove") == 0) {
                    // 如果是remove事件,打印提示信息即可
                    printf("USB device removed
");
                }

                // 释放事件对象
                udev_device_unref(dev);
            }
        }
    }

    // 关闭monitor和udev对象
    udev_monitor_unref(monitor);
    udev_unref(udev);
    return 0;
}

5.2 编译脚本Makefile

CROSS=arm-linux-gnueabihf-
CC = $(CROSS)gcc
CFLAGS = -Wall -Wextra -pedantic -std=c99 
			-lpthread -lusb-1.0 -ludev 
			-I/home/alientek/tools/libusb-1.0.26/build/include	
			-I/home/alientek/tools/eudev-3.2.11/build/include

LDFLAGS = -L/home/alientek/tools/libusb-1.0.26/build/lib 
			-L/home/alientek/tools/eudev-3.2.11/build/lib


TARGET = usb_callback_test
OBJS = $(TARGET).o

$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
	cp -f ${TARGET} ~/linux/nfs/rootfs-alientek/

%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

clean:
	rm -f $(OBJS) $(TARGET)

5.3 运行结果

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。