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

news2024/11/26 14:26:09

目录

零、前言

一、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 前言

参考: libusb 和 usbutils 的交叉编译 (ngui.cc)
库版本:usbutils-005 ( Index of /pub/linux/utils/usb/usbutils/ (kernel.org))

2.1 交叉编译

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

三、libudev交叉编译

3.0 前言

参考: 交叉编译libudev_libudev交叉编译_xqhrs232的博客-CSDN博客
库版本: 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:\n");
    printf("  devpath   : %s\n", devpath  );
    printf("  subsystem : %s\n", subsystem);
    printf("  devtype   : %s\n", devtype  );
    printf("  syspath   : %s\n", syspath  );
    printf("  sysname   : %s\n", sysname  );
    printf("  sysnum    : %s\n", sysnum   );
    printf("  devnode   : %s\n", devnode  );
    printf("\n");
}

// 遍历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\n");
        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\n");
                    // enumerate_usb_devices(udev);
                }
                else if (strcmp(action, "remove") == 0) {
                    // 如果是remove事件,打印提示信息即可
                    printf("USB device removed\n");
                }

                // 释放事件对象
                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 运行结果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/475430.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库】索引与事务

目录 1、索引 1.1、概念 1.2、索引的作用 1.3、 索引的缺点 1.4、数据库中实现索引的数据结构 1.4.1、B树/B-树 1.4.2、B树 1.4.3、回表 1.5、使用场景 1.6、索引的使用 1.6.1、查看索引 1.6.2、创建索引 1.6.3、 删除索引 1.7、索引的分类 2、事务 2.1、为什…

Arduino ESP8266基于ESPAsyncWebServer 网页GPIO控制

Arduino ESP8266基于ESPAsyncWebServer 网页GPIO控制 📍相关篇《Arduino ESP8266利用AJAX局部动态更新网页内容》 📺控制页面演示: 🌿在手机上可以通过接入ESP8266的WIFI,通过浏览器方位192.168.4.1进行网页页面操控引脚以及查看esp8266信息。 ✨本项目是基于github上…

[oeasy]python0143_主控程序_main

主控程序 回忆上次内容 上次把 apple.py 拆分成了 输入主函数 引用模块中变量的时候 要带上包(module)名 get_fruits.aget_fruits.b 最终 拆分代码 成功&#xff01; 可以将程序 再拆分成 输入输出 然后 再由主函数调用吗&#xff1f;&#x1f914; 建立主控 新建一个 ma…

【Java笔试强训 10】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;井字棋 …

大数据技术之大数据概论

第1章 大数据概念 大数据(Big Data): 指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产 大数据主要解决&#xff0c;海量数据的采集、存…

【吴恩达推荐】《ChatGPT Prompt Engineering for Developers》- 知识点目录

《ChatGPT Prompt Engineering for Developers》 1 Introduction 2 Guidelines Principle 1: Write clear and specific instructions Tactic 1: Use delimiters Tactic 3: “If-statement” Check whether conditions are satisfiedCheck assumptions required to do the …

RDD的Stage划分原理

1. 什么是RDD RDD&#xff08;Resilient Distributed Dataset&#xff09;叫做分布式数据集&#xff0c;是Spark 中最基本的数据抽象&#xff0c;它代表一个不可变、可分区、里面的元素可并行计算的集合。在Spark 中&#xff0c;对数据的所有操作不外乎创建RDD、转化已有RDD 以…

JavaBeaneljstl

1.JavaBean 1.1 什么是JavaBean JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean&#xff0c;类必须是具体的和公共的&#xff0c;并且具有无参数的构造器 简单一点&#xff1a;建一个类,给一个无参的构造方法. 它就是JavaBean&#xff0c;对应JavaBean来说&#x…

【C++】程序员的屠龙母鸡:二叉树进阶OJ题详解

不会自动生成&#xff0c;还是我自己写目录吧 -.- 文章目录 前言一、稍微简单一点的二叉树OJ题二、相对困难一点的二叉树OJ题总结 前言 在看这篇文章前希望大家是学过二叉树的&#xff0c;不然理解起来可能会比较费劲&#xff0c;但我会尽自己的努力让大家学会这些题&#xf…

TensorFlow会被JAX代替吗,使用JAX训练第一个机器学习模型

上期文章我们分享了JAX的概念&#xff0c;Jax 是来自 Google 的一个相对较新的机器学习库。它更像是一个 autograd 库&#xff0c;可以区分每个本机 python 和 NumPy 代码。 “PythonNumPy 程序的可组合转换&#xff1a;微分、向量化、JIT 到 GPU/TPU 等等”。该库利用 grad 函…

vue 视频播放插件vue-video-player自定义样式

1、背景 项目中有涉及视频播放的需求&#xff0c;并且UI设计了样式&#xff0c;与原生的视频video组件有差异&#xff0c;所以使用了vue-video-player插件&#xff0c;并对vue-video-player进行样式改造&#xff0c;自定义播放暂停按钮、全屏按钮、时间进度条样式等 2、效果图…

10分钟叫你如何学会组织Prompt语言同AI沟通

提示词&#xff08;Prompt&#xff09;是与AI模型交流的语言&#xff0c;用以告诉AI模型想要生成的图像的特征。提示词的准确性、精准度直接决定了生成的图像是否符合我们的预期。 基础介绍 AIGC提示词通常由多个单词、词组或短句构成&#xff0c;以***,***分割组成&#xff…

如何更改Windows服务器时间

Windows操作系统自带时间同步功能&#xff0c;它会自动从互联网时间服务器获取时间&#xff0c;以保证系统时间的准确性。但是&#xff0c;有时候我们需要更改时间服务器&#xff0c;以获得更准确的时间同步。小编将为大家介绍如何更改Windows时间服务器&#xff0c;以及Window…

java基础知识——22.lambda表达式

这篇文章&#xff0c;我们来讲一下java的lambda表达式 目录 1.初识lambda表达式 2.lambda表达式介绍 2.1 函数式编程 2.2 lambda表达式的具体格式 2.3 Lambda表达式的好处 2.4 Lambda的省略写法 1.初识lambda表达式 首先&#xff0c;我们来看一下lambda表达式的应用 下…

运维——ssh无法登录云服务器

0x00 概述 一般来讲&#xff0c;无法登录ssh的原因挺多&#xff0c;如果无法登录云服务器&#xff0c;则除了要检查ssh端口是否放行&#xff0c;防火墙状态外&#xff0c;还需要检查云服务器web控制台入站规则是否开放了对应端口。如果你前面检查都是正常&#xff0c;那么还需…

实战打靶集锦-017-potato

提示&#xff1a;本文记录了博主的一次打靶过程 目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 Apache探查4.2 ProFTPD探查4.2.1 strcmp()函数绕过4.2.2 查找apache日志文件4.2.3 查看/etc/passwd文件4.2.4 破译密码4.2.5 突破边界 5. 提权5.1 系统信息枚举5.2 定时任…

基于Yolov5的NEU-DET钢材表面缺陷检测,优化组合新颖程度较高:CVPR2023 DCNV3和InceptionNeXt,涨点明显

1.钢铁缺陷数据集介绍 NEU-DET钢材表面缺陷共有六大类,分别为:crazing,inclusion,patches,pitted_surface,rolled-in_scale,scratches 每个类别分布为: 训练结果如下: 2.基于yolov5s的训练 map值: 2.1 Inception-MetaNeXtStage 对应博客:https://cv2023.blog.csdn.n…

实验5 彩色图像处理与图像变换

文章目录 一、实验目的二、实验内容1. 彩色图像平滑。(课本P310 例6.12)2. 彩色边缘检测。(课本P318 例6.16)3. 一维小波变换。(课本P364 例7.20)4. 二维小波变换。(课本P369 例7.22)5. 小波包分解。(课本P376 例7.24) 一、实验目的 掌握RGB彩色模型和HSI彩色模型之间的转换方…

C语言指针的使用

文章目录 前言一、指针基本概念介绍二、指针的大小三、使用指针访问变量和变量地址四、使用指针遍历数组总结 前言 一、指针基本概念介绍 在 C 语言中&#xff0c;指针是一种用于存储内存地址的数据类型。指针可以存储任何数据类型的内存地址&#xff0c;包括基本数据类型、数…

C语言之单链表的实现以及链表的介绍

一、为什么会存在链表 因为我们常用的顺序表会存在以下的一些问题&#xff1a; 1. 中间/头部的插入删除&#xff0c;时间复杂度为O(N) 2. 增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间。会有不小的消耗。 3. 增容一般是呈2倍的增长&#xff0c;势必会有一定…