龙芯2k0300 - 智能车走马观碑组VL53L0X驱动移植

news2026/5/13 18:16:50
----------------------------------------------------------------------------------------------------------------------------开发板 久久派开发板eMMC8GBDDR4512MBu-bootu-boot 2022.04linux6.12rootfsbuildroot-2024.08----------------------------------------------------------------------------------------------------------------------------在《龙芯2k0300- 走马观碑组第21届智能汽车竞赛软硬件设计》中我们介绍到我们的开发板使用了1.8寸TFT显示模块Vl53l0X是ST推出的第二代FlightSense技术的飞行时间传感器与传统的测距传感器不同它使用时飞行时间(Time-of-FlightTOF)测量原理可以实现精确、快速的非接触式测量。无论目标颜色和反射率如何都可以进行距离测量抗干扰能力更强。Vl53l0X激光测距模块的原理是利用激光脉冲的飞行时间来测量距离。该模块通过发射一束激光脉冲并测量该激光脉冲从发射到被接收的时间来计算出物体与传感器之间的距离。更多相关资料参考《STM32传感器模块编程实践(九)VL53L0X激光红外测距传感器简介及驱动源码》。Vl53l0X激光测距模块采用I2C通信方式Vl53l0X激光测距采用I2C通信方式与龙芯2K0300开发板的连接关系需严格对应确保I2C通信与GPIO控制正常连接表如下屏幕引脚功能连接的龙芯GPIO说明VIN为Vl53l0X提供工作电压3.3V接3.3VGND电源共地确保电压稳定性GND必须可靠接地否则可能出现显示异常SCLI2C 时钟引脚I2C1_SCL (GPIO50)提供I2C同步通信时钟SDASDA数据引脚I2C1_SDA(GPIO51)传输I2C命令与显示数据INT传感器测量完成后会输出一个中断信号——不接也能用只是不能用中断方式内核IIO驱动一般不用它轮询即可XS模块复位引脚1复位、关机0正常工作——不接也能正常用接 GPIO 可以实现软件复位、省电一、VL53L0X设备驱动VL53L0X由于采用了I2C通讯协议所以涉及到了I2C设备驱动。如果对I2C驱动源码移植感兴趣可参考《通信协议-I2C》《linux驱动移植-I2C总线设备驱动》《linux驱动移植-I2C适配器驱动移植》《linux驱动移植-I2C驱动移植(OLED SSD1306)》。龙邱科技提供了VL53L0X设备驱动实现位于i2c_vl53l0x_driver只不过这个是基于linux 4.19的如果移植这个改动的相对较多。此外我们在《龙芯2k0300- 久久派开发环境搭建及内核升级(下)》驱动移植章节下载的linux-6.9-WuwuSama-99pi.tar.gz中也包含了驱动代码位于drivers/wuwu_drivers/wuwu_vl53l0x.c文件中。1.1 内核配置实际上我们下载的内核linux 6.12已经内置了VL53L0X的驱动其使用了IIO框架这里我们就直接使用内核驱动即可无需从零开发驱动需开启内核I2C及IIO相关配置并添加VL53L0X驱动代码实现激光测距。进入内核配置界面zhengyangubuntu:~$ cd /opt/2k0300/build-2k0300/workspace/linux-6.12 zhengyangubuntu:/opt/2k0300/build-2k0300/workspace/linux-6.12$ source ../set_env.sh make menuconfig依次进入以下菜单Device Drivers → I2C support → I2C Hardware Bus support → * Loongson fast speed I2C adapter # 龙芯 2K0300 I2C控制器驱动 * I2C device interface [*] Industrial I/O support → Proximity and distance sensors → * STMicroelectronics VL53L0X ToF ranger sensor (I2C)默认会生成配置CONFIG_I2C_LSFSy # 这个已经配置不用追加 CONFIG_I2C_CHARDEVy CONFIG_IIOy # 这个已经配置不用追加 CONFIG_VL53L0X_I2Cy我们直接修改arch/loongarch/configs/loongson_2k300_defconfig文件加入这几个配置。1.2VL53L0X驱动驱动源码位于drivers/iio/proximity/vl53l0x-i2c.cvl53l0x-i2c.c驱动基于内核IIO框架开发无需修改内核核心代码只需编译进内核即可。1.2.1vl53l0x-i2c.cdrivers/iio/proximity/vl53l0x-i2c.c源码如下点击查看详情// SPDX-License-Identifier: GPL-2.0 /* * Support for ST VL53L0X FlightSense ToF Ranging Sensor on a i2c bus. * * Copyright (C) 2016 STMicroelectronics Imaging Division. * Copyright (C) 2018 Song Qiang songqiang1304521gmail.com * Copyright (C) 2020 Ivan Drobyshevskyi drobyshevskyigmail.com * * Datasheet available at * https://www.st.com/resource/en/datasheet/vl53l0x.pdf * * Default 7-bit i2c slave address 0x29. * * TODO: FIFO buffer, continuous mode, range selection, sensor ID check. */ #include linux/delay.h #include linux/gpio/consumer.h #include linux/i2c.h #include linux/irq.h #include linux/interrupt.h #include linux/module.h #include linux/iio/iio.h #define VL_REG_SYSRANGE_START 0x00 #define VL_REG_SYSRANGE_MODE_MASK GENMASK(3, 0) #define VL_REG_SYSRANGE_MODE_SINGLESHOT 0x00 #define VL_REG_SYSRANGE_MODE_START_STOP BIT(0) #define VL_REG_SYSRANGE_MODE_BACKTOBACK BIT(1) #define VL_REG_SYSRANGE_MODE_TIMED BIT(2) #define VL_REG_SYSRANGE_MODE_HISTOGRAM BIT(3) #define VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO 0x0A #define VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY BIT(2) #define VL_REG_SYSTEM_INTERRUPT_CLEAR 0x0B #define VL_REG_RESULT_INT_STATUS 0x13 #define VL_REG_RESULT_RANGE_STATUS 0x14 #define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0) struct vl53l0x_data { struct i2c_client *client; struct completion completion; struct regulator *vdd_supply; struct gpio_desc *reset_gpio; }; static irqreturn_t vl53l0x_handle_irq(int irq, void *priv) { struct iio_dev *indio_dev priv; struct vl53l0x_data *data iio_priv(indio_dev); complete(data-completion); return IRQ_HANDLED; } static int vl53l0x_configure_irq(struct i2c_client *client, struct iio_dev *indio_dev) { int irq_flags irq_get_trigger_type(client-irq); struct vl53l0x_data *data iio_priv(indio_dev); int ret; if (!irq_flags) irq_flags IRQF_TRIGGER_FALLING; ret devm_request_irq(client-dev, client-irq, vl53l0x_handle_irq, irq_flags, indio_dev-name, indio_dev); if (ret) { dev_err(client-dev, devm_request_irq error: %d\n, ret); return ret; } ret i2c_smbus_write_byte_data(data-client, VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); if (ret 0) dev_err(client-dev, failed to configure IRQ: %d\n, ret); return ret; } static void vl53l0x_clear_irq(struct vl53l0x_data *data) { struct device *dev data-client-dev; int ret; ret i2c_smbus_write_byte_data(data-client, VL_REG_SYSTEM_INTERRUPT_CLEAR, 1); if (ret 0) dev_err(dev, failed to clear error irq: %d\n, ret); ret i2c_smbus_write_byte_data(data-client, VL_REG_SYSTEM_INTERRUPT_CLEAR, 0); if (ret 0) dev_err(dev, failed to clear range irq: %d\n, ret); ret i2c_smbus_read_byte_data(data-client, VL_REG_RESULT_INT_STATUS); if (ret 0 || ret 0x07) dev_err(dev, failed to clear irq: %d\n, ret); } static int vl53l0x_read_proximity(struct vl53l0x_data *data, const struct iio_chan_spec *chan, int *val) { struct i2c_client *client >1.2.2IIO框架介绍工业I/O(IIO)是专用于模数转换器(ADC)和数模转换器(DAC)的内核子系统。随着越来越多的具有不同代码实现的传感器分散在内核源上收集它们变得必要这就是IIO框架以通用的方式所做的事情。加速度计陀螺仪电流/电压测量芯片光传感器压力传感器等都属于IIO系列器件。IIO框架如下所示IIO子系统通过cdev向文件系统注册字符设备提供应用层访问IIO子系统的接口也使用sysfs框架向应用层提供在Linux文件系统中修改访问的接口前者在用户驱动使用trigger或buffer模式时使用后者则在direct模型下使用。下面是用户空间与IIO驱动程序交互的两种方式/dev/iio:deviceX: 表示导出设备事件和数据缓冲区的字符设备/sys/bus/iio/devices/iio:deviceX/表示传感器及其通道IIO子系统又core、trigger、buffer和event几个模块组成用户驱动根据自身需求使用IIO子系统提供的注册接口向子系统注册对应的channel信息以及访问的接口这些信息与接口将有子系统在用户访问时分配访问和回调。接下来我们简要分析一下vl53l0x-i2c.c驱动源码。1.2.2.1 结构体及变量定义结构体以及初始化变量vl53l0x_data存放传感器私有数据vl53l0x_channels通道定义vl53l0x_infoIIO设备操作集。源码如下struct vl53l0x_data { struct i2c_client *client; // I2C设备 struct completion completion; // completion内部有个计数器 0未完成需要等待 1已完成可以继续 struct regulator *vdd_supply; // 电源 struct gpio_desc *reset_gpio; // 复位引脚对应的GPIO描述符 }; static const struct iio_chan_spec vl53l0x_channels[] { // 测距 { // 这个通道的类型是距离(distance)在/sys/... 目录下生成in_distance_raw、in_distance_scale .type IIO_DISTANCE, // 这个通道支持哪些读取操支持读原始数据(距离值)、读比例值(单位换算毫米转米) .info_mask_separate BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), }, }; // IIO设备操作集 static const struct iio_info vl53l0x_info { .read_raw vl53l0x_read_raw, // 读数据 };1.2.2.2 读取测距数据IIO接口函数read_raw用于读取原始数据(寄存器值)static int vl53l0x_read_proximity(struct vl53l0x_data *data, const struct iio_chan_spec *chan, int *val) { struct i2c_client *client >static irqreturn_t vl53l0x_handle_irq(int irq, void *priv) { // 获取私有数据 struct iio_dev *indio_dev priv; struct vl53l0x_data *data iio_priv(indio_dev); // 标记测距完成 complete(data-completion); return IRQ_HANDLED; }如果使用了中断就需要向内核申请中断并注册中断处理函数vl53l0x_handle_irqstatic int vl53l0x_configure_irq(struct i2c_client *client, struct iio_dev *indio_dev) { // 从设备树里读取中断触发类型 int irq_flags irq_get_trigger_type(client-irq); // 获取私有数据 struct vl53l0x_data *data iio_priv(indio_dev); int ret; if (!irq_flags) irq_flags IRQF_TRIGGER_FALLING; // 向内核申请中断号注册中断处理函数 最后一个参数传给中断函数的参数 ret devm_request_irq(client-dev, client-irq, vl53l0x_handle_irq, irq_flags, indio_dev-name, indio_dev); if (ret) { dev_err(client-dev, devm_request_irq error: %d\n, ret); return ret; } // 往VL53L0X的寄存器写配置当新的测距数据准备好时触发 INT中断 ret i2c_smbus_write_byte_data(data-client, VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); if (ret 0) dev_err(client-dev, failed to configure IRQ: %d\n, ret); return ret; }1.2.2.3probe函数当设备树与驱动成功匹配后内核自动调用vl53l0x_probe函数完成传感器的初始化、上电、注册让驱动可以工作。static int vl53l0x_probe(struct i2c_client *client) { struct vl53l0x_data *data; struct iio_dev *indio_dev; int error; // 1. 向内核申请一块内存用于创建IIO设备 indio_dev devm_iio_device_alloc(client-dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; // 2. 初始化私有数据 data iio_priv(indio_dev); >1.3 新增设备节点这里我们将VL53L0X测距模块接到i2c1接口因此需要适当调整设备树。1.3.1i2c1i2c1节点定义在arch/loongarch/boot/dts/loongson-2k0300.dtsii2c1: i2c10x16109000 { compatible loongson,lsfs-i2c; reg 0 0x16109000 0 0x1000; #address-cells 1; #size-cells 0; interrupt-parent liointc0; interrupts 4 IRQ_TYPE_LEVEL_HIGH; pinctrl-0 i2c1_pins; pinctrl-names default; clock-frequency 200000000; status disabled; };其中i2c1:标签用于在设备树中其他地方通过i2c1引用这个节点方便添加属性或修改状态i2c10x16109000节点名格式为设备名寄存器基地址。这里i2c1是功能名0x16109000是该I2C控制器的物理寄存器基地址。compatible驱动匹配字符串。内核通过该属性寻找能驱动此设备的驱动程序reg寄存器地址范围。格式为地址高位 地址低位 长度高位 长度低位由于龙芯采用64位寻址这里用两个32位数表示64位地址#address-cells和#size-cells定义该节点下子节点(即挂载的I2C从设备)的地址和长度格式。#address-cells 1子节点的reg属性中地址部分占用1个32位单元。对于I2C设备这通常是7位从设备地址#size-cells 0子节点的reg属性中没有长度字段(因为I2C设备地址不涉及地址范围)interrupt-parent指定该设备的中断路由到哪个中断控制器。liointc0是龙芯2K0300内部的中断控制器节点(即龙芯I/O中断控制器)的标签interrupts描述中断线的具体信息4硬件中断编号(对应I2C1控制器在中断控制器中的编号)IRQ_TYPE_LEVEL_HIGH中断触发类型这里定义为高电平触发。该宏在dt-bindings/interrupt-controller/irq.h中定义。pinctrl-0指定设备使用的第一组引脚配置i2c1_pins是另一个设备树节点的标签该节点描述了I2C1的SCL和SDA引脚应复用为I2C功能并可能包含上拉等电气属性pinctrl-names为引脚的配置状态命名与pinctrl-0对应。default是默认状态驱动在probe时会自动应用pinctrl-0的配置引脚配置设置为i2c1_pinsclock-frequencyI2C控制器的输入时钟频率(单位Hz)status设备状态此时处于禁用状态。更多有关设备树相关的内容可以参考《linux设备树-基础介绍》。1.3.2vl53l0x29zhengyangubuntu:~$ cd /opt/2k0300/build-2k0300/workspace/linux-6.12 zhengyangubuntu:/opt/2k0300/build-2k0300/workspace/linux-6.12$ vim arch/loongarch/boot/dts/ls2k300_99pi.dtsi修改arch/loongarch/boot/dts/ls2k300_99pi.dtsi// 在根节点或合适位置(通常是 soc 内)引用并启用 I2C1 i2c1 { status okay; // VL53L0X 传感器 vl53l0x29 { compatible st,vl53l0x; reg 0x29; status okay; }; };通过i2c1引用这个节点将status改为okay同时添加了I2C从设备节点。其中vl53l0x29设备节点下的compatible名称要和vl53l0x-i2c.c驱动中的vl53l0x_driver.driver.of_match_table里的名称匹配。static const struct i2c_device_id vl53l0x_id[] { { vl53l0x }, { } }; MODULE_DEVICE_TABLE(i2c, vl53l0x_id); static const struct of_device_id st_vl53l0x_dt_match[] { { .compatible st,vl53l0x, }, { } }; MODULE_DEVICE_TABLE(of, st_vl53l0x_dt_match); static struct i2c_driver vl53l0x_driver { .driver { .name vl53l0x-i2c, .of_match_table st_vl53l0x_dt_match, }, .probe vl53l0x_probe, .id_table vl53l0x_id, };这样在适配器注册的时候会遍历i2c设备树节点下的所有子设备节点从而实现注册该控制器下的所有I2C从设备具体可以参考《I2C适配器注册》源码部分。1.3.3i2c1_pinsi2c1_pins定义在arch/loongarch/boot/dts/loongson-2k0300.dtsipinmux: pinmux16000490 { ...... i2c1_pins: pinmux_G50_G51_as_i2c1 { pinctrl-single,bits 0xc 0x000000f0 0x000000f0; }; ...... }这个设备树节点是使用pinctrl-single驱动来配置引脚复用功能的典型写法这行代码会在寄存器0x1600049c的7:4位写入0xf而其他位保持不变用于将芯片的GPIO50和GPIO51这两个引脚设置为I2C1功能。注pinctrl-single是一个通用的引脚控制驱动适用于那些引脚复用寄存器是“单寄存器位域”的芯片。当SoC没有提供复杂的pinctrl框架时可以直接用这种方式“裸写”寄存器。二、应用程序接下来我们在example目录下创建子目录vl53l0x_appzhengyangubuntu:/opt/2k0300/loongson_2k300_lib/example$ mkdir vl53l0x_app目录结构如下zhengyangubuntu:/opt/2k0300/loongson_2k300_lib/example/vl53l0x_app$ tree . . ├── main.c └── Makefile2.1main.c内核自带驱动把VL53L0X注册成IIO传感器应用层直接读文件即可获取距离。下面编写一个简单的测试应用程序用于读取距离并打印/* * 测试 VL53L0X 驱动 */ #include stdio.h #include fcntl.h #include unistd.h #include stdlib.h // 1. 新增需要包含 atoi 函数的头文件 /* 设备节点路径 */ #define DEVICE_PATH /sys/bus/iio/devices/iio:device1/in_distance_raw int main(int argc, char **argv) { int fd; char buf[16]; int distance; // 2. 新增用于存储转换后的整数距离 /* 1. 打开设备 */ fd open(DEVICE_PATH, O_RDONLY); if (fd 0) { perror(open); return -1; } printf(Opened %s successfully.\n, DEVICE_PATH); /* 2. 循环读取距离值 */ while (1) { lseek(fd, 0, SEEK_SET); read(fd, buf, 16); // 3. 修改将字符串转换为整数 distance atoi(buf); // 4. 修改使用 %d 格式打印整数输出将非常干净 printf(Distance: %d mm\n, distance); /* 控制打印频率 */ usleep(200000); // 200ms } close(fd); return 0; }2.2Makefileall: loongarch64-linux-gnu-gcc -o main main.c clean: rm -rf *.o main2.3 编译应用程序zhengyangubuntu:/opt/2k0300/loongson_2k300_lib/example/vl53l0x_app$ make loongarch64-linux-gnu-gcc -o main main.c zhengyangubuntu:/opt/2k0300/loongson_2k300_lib/example/vl53l0x_app$ ll -rwxrwxr-x 1 zhengyang zhengyang 20680 3月 26 16:00 main* -rw-rw-r-- 1 zhengyang zhengyang 740 3月 26 16:00 main.c -rw-rw-r-- 1 zhengyang zhengyang 71 3月 24 14:24 Makefile三、测试3.1 烧录设备树3.1.1 编译设备树如果需要单独编译设备树在linux内核根目录执行如下命令zhengyangubuntu:~$ cd /opt/2k0300/build-2k0300/workspace/linux-6.12 zhengyangubuntu:/opt/2k0300/build-2k0300/workspace/linux-6.12$ source ../set_env.sh make dtbs V13.1.2 更新设备树将设备树拷贝到久久派的/opt目录zhengyangubuntu:/opt/2k0300/build-2k0300/workspace/linux-6.12$ scp arch/loongarch/boot/dts/ls2k300_99pi_wifi.dtb root172.23.34.188:/opt在久久派使用dd命令烧写设备树到SPI Nor Flash的dtb分区[rootLS-GD opt]# dd if/opt/ls2k300_99pi_wifi.dtb of/dev/mtdblock3 bs1 221240 records in 221240 records out 22124 bytes (22 kB, 22 KiB) copied, 0.500342 s, 44.2 kB/s3.2 安装驱动由于我们在内核配置环节将驱动配置到内核中了因此需要重新编译内核并烧录内核。3.2.1 编译内核ubuntu宿主接重新编译内核zhengyangubuntu:/opt/2k0300/build-2k0300/workspace/linux-6.12$ source ../set_env.sh make uImage -j$(nproc)3.2.2 烧录内核久久派烧录内核即将编译生成的uImage(内核镜像)拷贝到/boot目录[rootLS-GD ~]# scp zhengyang172.23.34.187:/opt/2k0300/build-2k0300/workspace/linux-6.12/arch/loongarch/boot/uImage /boot/ [rootLS-GD ~]# reboot3.2.3 查看i2c信息我们将龙邱Vl53l0X激光测距模块接入开发板的I2C1接口处进入I2C总线的控制目录# I2C 总线的控制目录 [rootLS-GD ~]# cd /sys/bus/i2c/ [rootLS-GD i2c]# ls -l drwxr-xr-x 2 root root 0 Jul 24 20:49 devices drwxr-xr-x 10 root root 0 Jul 24 20:49 drivers -rw-r--r-- 1 root root 16384 Jul 24 20:51 drivers_autoprobe --w------- 1 root root 16384 Jul 24 20:51 drivers_probe --w------- 1 root root 16384 Jul 24 20:49 uevent其中devices列出了所有连接在I2C总线上的设备drivers列出了所有已注册的I2C驱动程序drivers_autoprobe、drivers_probe这些是控制文件用于手动触发驱动探测或设置自动探测。进入设备列表目录查看具体挂载了哪些硬件[rootLS-GD i2c]# cd devices/ [rootLS-GD devices]# ls -l # i2c-1代表I2C控制器 1-0029代表连接在 i2c-1 总线上的设备。 lrwxrwxrwx 1 root root 0 Jul 24 20:49 1-0029 - ../../../devices/platform/2k300-soc/16109000.i2c1/i2c-1/1-0029 lrwxrwxrwx 1 root root 0 Jul 24 20:49 i2c-1 - ../../../devices/platform/2k300-soc/16109000.i2c1/i2c-1进入了这个地址为0x29的设备目录[rootLS-GD devices]# cd 1-0029 [rootLS-GD 1-0029]# ls -l lrwxrwxrwx 1 root root 0 Jul 24 20:52 driver - ../../../../../../bus/i2c/drivers/vl53l0x-i2c drwxr-xr-x 3 root root 0 Jul 24 20:49 iio:device1 -r--r--r-- 1 root root 16384 Jul 24 20:49 modalias -r--r--r-- 1 root root 16384 Jul 24 20:49 name lrwxrwxrwx 1 root root 0 Jul 24 20:52 of_node - ../../../../../../firmware/devicetree/base/2k300-soc/i2c10x16109000/vl53l0x29 drwxr-xr-x 2 root root 0 Jul 24 20:52 power lrwxrwxrwx 1 root root 0 Jul 24 20:49 subsystem - ../../../../../../bus/i2c -rw-r--r-- 1 root root 16384 Jul 24 20:49 uevent其中driver绑定的驱动内核已经设备和vl53l0x-i2c驱动绑定在了一起iio:device1生成的输入设备节点of_node设备树节点匹配。3.2.4 查看iio信息查看IIO设备相关文件[rootLS-GD i2c]# ls /sys/bus/iio/devices/iio\:device1/ -l total 0 -rw-r--r-- 1 root root 16384 Jul 24 20:56 in_distance_raw -rw-r--r-- 1 root root 16384 Jul 24 20:56 in_distance_scale -r--r--r-- 1 root root 16384 Jul 24 20:49 name lrwxrwxrwx 1 root root 0 Jul 24 20:56 of_node - ../../../../../../../firmware/devicetree/base/2k300-soc/i2c10x16109000/vl53l0x29 drwxr-xr-x 2 root root 0 Jul 24 20:56 power lrwxrwxrwx 1 root root 0 Jul 24 20:49 subsystem - ../../../../../../../bus/iio -rw-r--r-- 1 root root 16384 Jul 24 20:49 uevent -r--r--r-- 1 root root 16384 Jul 24 20:56 waiting_for_supplier查看传感器名称[rootLS-GD i2c]# cat /sys/bus/iio/devices/iio\:device1/name vl53l0xin_distance_raw存放的是传感器的原始数据[rootLS-GD i2c]# cat /sys/bus/iio/devices/iio\:device1/in_distance_raw 1093.3 应用程序测试我们将龙邱Vl53l0X激光测距模块接入开发板的I2C1接口处同时用手挡住遮挡激光测距模块。在久久派开发板执行如下命令[rootLS-GD opt]# scp zhengyang172.23.34.187:/opt/2k0300/loongson_2k300_lib/example/vl53l0x_app/main ./ zhengyang172.23.34.187s password: main 100% 20KB 1.4MB/s 00:00 [rootLS-GD opt]# ./main Distance: 151 mm Distance: 154 mm Distance: 159 mm Distance: 163 mm Distance: 167 mm Distance: 173 mm Distance: 174 mm Distance: 175 mm Distance: 173 mm Distance: 175 mm Distance: 177 mm Distance: 177 mm Distance: 181 mm Distance: 175 mm Distance: 169 mm Distance: 161 mm Distance: 146 mm观察输出每隔约200ms打印一次距离(单位毫米)按CtrlC退出。四、代码下载loongson_2k300_lib参考文章[1]LS2K0300久久派_V1.1板卡使用手册v1.2_20240705.pdf[2] [Linux IIO驱动[3]Linux下IIO子系统的使用与源码分析[4]Linux下IIO子系统驱动[5]linux IIO驱动框架开发流程说明

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…