自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(58)
  • 收藏
  • 关注

原创 [I/O多路复用] epoll 操作

epoll是 Linux 中用于的机制。它和selectpoll的目标类似:让一个线程同时监听多个文件描述符,判断哪些 fd 已经可以读、可以写,或者发生异常。但epoll的设计更适合高并发场景。它不是每次调用都把所有 fd 传给内核,而是先把要监听的 fd 注册到内核维护的 epoll 实例中,之后通过epoll_wait等待就绪事件。

2026-04-29 11:02:34 415

原创 [I/O多路复用] poll 函数

对于普通 socket,通常表示有数据可读,或者对端关闭连接。对于监听 socket,通常表示有新连接到来,可以调用。是用于监视的文件描述符结构体数组,每个元素包含了一个文件描述符以及该文件描述符关注的事件类型和发生的事件类型。它允许一个线程同时监视多个文件描述符,判断哪些描述符已经可以读、可以写,或者发生异常。使用数组,理论上可以监听更多 fd,实际限制主要来自进程可打开文件描述符数量。第二,调用返回后,用户程序仍然需要线性扫描整个数组,找出哪些 fd 就绪。表示立即返回,不阻塞,常用于轮询。

2026-04-29 11:01:33 222

原创 [I/O多路复用] select 函数

它允许一个线程同时监视多个文件描述符,判断哪些描述符已经可以进行读、写,或者发生异常。对于 socket 来说,可读通常表示有数据到达、对端关闭连接,或者监听 socket 上有新连接到来。是异常事件集合,常用于检测 socket 的带外数据等异常情况,实际使用较少。第三,内核和用户态之间需要来回复制 fd 集合,fd 数量大时开销明显。调用返回后,集合中只保留已经就绪的 fd。需要监听的文件描述符数量,是所有文件描述符中最大值+1。,调用后还要线性扫描所有 fd,效率较低。第一,文件描述符数量有限。

2026-04-29 11:00:31 53

原创 [T113] 交叉编译 libmpv

FFmpeg 的 ALSA 检测在 Tina sysroot 下会卡头文件。,Meson 实际优先使用 cross file 里的。条目,必须显式改成 wrapper。这里是最终跑通的版本,关键是。HarfBuzz 不能用。

2026-03-25 17:52:15 287

原创 [T113] 交叉编译 OpenCV 4.5.2 + face 模块

保存为:~/opencv-4.5.2/build_t113/toolchain_t113.cmake。(16 模块 × 3 个 so 链接/版本文件)

2026-03-25 17:51:25 245

原创 [mpv] libmpv 使用介绍

libmpv是 mpv 提供的,用于在程序里直接控制 mpv,而不需要处理 socket 和 JSON 文本。它的核心模型和 JSON IPC 一样,仍然围绕命令(commands)属性(properties)选项(options)和事件(events)展开。mpv 官方示例仓库明确说明,libmpv 的主要文档入口就在,并且“几乎所有事情”都是通过命令和属性完成的。

2026-03-18 11:20:30 717

原创 [mpv] 通过 JSON IPC 控制 mpv 播放器

是要执行的命令名称,后跟参数列表。然后 mpv 将发送一个回复,指示命令是否正确运行,以及一个包含命令特定返回数据的附加字段(也可以为空)。这些命令都基于 mpv 的命令/属性模型,经由 JSON IPC 以结构化 JSON 的方式发送。外部程序连接这个 IPC 端点后,就可以给 mpv 发送命令,也可以接收 mpv 推送的事件。这意味着 mpv 可以在状态变化时主动给客户端发消息,而不是每次都要客户端轮询。持续读取 socket,既处理命令响应,也处理异步事件。,命令回复会将其设置为 0。

2026-03-18 11:17:56 471

原创 SQLite3学习笔记8:同步查询接口 sqlite3_get_table(C API)

因此 SQLite 提供了一个它可以,以二维表形式返回。

2026-03-05 09:28:14 131

原创 SQLite3学习笔记7:prepare + bind(C API)

关键:UPDATE 一定要写 WHERE(避免全表误更新)关键:DELETE 一定要写 WHERE(避免全表误删)2.2 带条件查询(WHERE xxx =?:插入一条数据(或循环插入多条)

2026-03-04 14:12:25 335

原创 SQLite3学习笔记6:UPDATE(改)+ DELETE(删)数据(C API)

【代码】SQLite3学习笔记6:UPDATE(改)+ DELETE(删)数据(C API)

2026-01-28 09:25:27 129

原创 SQLite3学习笔记5:INSERT(写)+ SELECT(读)数据(C API)

【代码】SQLite3学习笔记5:INSERT(写)+ SELECT(读)数据(C API)

2026-01-27 14:10:20 145

原创 SQLite3学习笔记4:打开和关闭数据库 + 创建表(C API)

【代码】SQLite3学习笔记4:打开和关闭数据库 + 创建表(C API)

2026-01-27 14:08:10 121

原创 SQLite3学习笔记3:UTC和CST 时区偏差问题

原始数据存 UTC(国际标准,便于跨时区设备溯源),查询时转换为 CST(UTC+8)。直接存储 CST 时间 —— 适合仅在国内使用、无需跨时区的嵌入式设备。,所以数据库中记录的时间会比本地时间少 8 小时。:插入 / 更新时显式指定时区偏移,让。,而 Ubuntu 系统显示的是。

2026-01-27 14:06:32 317

原创 SQLite3学习笔记2:SQL 基础语法

SELECT 是嵌入式中读取数据的核心,支持 “全量查(调试)”、“指定字段查(省内存)”、“条件查(精准读)”,完全适配嵌入式设备内存有限的特点。数据表是存储数据的核心载体,嵌入式场景中常用 “设备参数 / 传感器数据 / 日志” 等表,以下是贴合嵌入式的表结构设计。命令后紧跟文件名即可实现 “不存在则创建、存在则打开”,这是嵌入式场景的核心特性(无需配置服务,直接操作文件)。嵌入式场景中,INSERT 用于将传感器数据、设备电压 / 电流等参数写入数据库,以下是适配嵌入式的语法和操作。

2026-01-27 14:04:45 724

原创 SQLite3学习笔记1:配置环境

【代码】SQLite3学习笔记1:配置环境。

2026-01-27 13:59:04 108

原创 网络编程:UDP Socket

UDP 没有连接,不知道数据从哪来,所以接收时必须同时拿“信的数据”和“发信人的地址”。UDP 使用与 TCP 完全相同的地址结构体,没有区别。UDP 没有连接,发送时必须每次都指定“发给谁”。负责接收数据,打印发送者 IP,并原样回传。负责发送数据到指定 IP,并等待回复。

2025-12-17 10:30:32 1082

原创 外设与接口:按键输入 (libgpiod)

以下是处理 GPIO 中断事件的核心 API。

2025-12-14 22:04:08 408

原创 [泰山派 Armbian] 基于 gpio-keys 驱动的按键处理

是 Linux 内核中的一个标准输入设备驱动,专门用于处理通过 GPIO 引脚连接的物理按键。它的核心作用就像一名翻译官,负责监测 GPIO 引脚上的电平变化,并转换成操作系统能识别的按键事件(如按下或抬起),然后上报给系统。为了简化软件配置,优先选择硬件默认电平与电路逻辑相符的引脚。应用层不需要包含任何 GPIO 相关的头文件,只需要标准的 Input 子系统头文件。文件放入系统指定的 Overlay 目录,并修改启动配置。,该文件描述了按键的物理属性和逻辑键值。下生成一个新的节点(例如。

2025-12-14 17:00:47 649

原创 网络编程:TCP Socket

传输控制协议。是一种面向连接的、可靠的、基于字节流的传输层通信协议。它通过“三次握手”建立连接,通过“确认应答”机制保证数据不丢失。

2025-12-10 16:54:51 867

原创 多线程编程:信号量

协调多个线程的执行顺序,使它们按照预定的逻辑次序运行。例如,线程 A 必须等待线程 B 完成某个任务后才能继续执行。信号量初始值设为 0,A 调用。POSIX 信号量分为无名信号量 和有名信号量。在多线程编程中,主要使用无名信号量。阻塞,B 完成后调用。

2025-12-10 13:25:22 889

原创 多线程编程:互斥锁

两个或多个线程互相持有对方需要的资源锁,且都在等待对方释放,导致无限等待。

2025-12-10 13:24:42 869

原创 多线程编程:数据传递与结果返回

在 C 语言中,线程函数的参数和返回值必须都是void *,这意味着任何数据类型(整数、浮点数、结构体)在传递时,都必须包装成指针。是void *;返回值也是void *。void *就像一个通用包裹,可以在里面装任何东西(一个数字、一个结构体、一个字符串),但必须确保包裹(指针)本身是有效的。有4种常见的方法来在线程间传递数据。

2025-12-09 14:56:33 447

原创 多线程编程:初识线程

一般情况下,进程中各个线程的运行是相互独立的,线程的终止并不会相互通知,也不会影响其他的线程, 终止的线程所占用的资源不会随着线程的终止而归还系统,而是仍为线程所在的进程持有, 这是因为一个进程中的多个线程是共享数据段的。在线程创建后,系统就开始运行相关的线程函数,在该函数运行完之后,该线程也就退出了, 这是线程的一种隐式退出的方法。函数是用于创建一个线程的,创建线程实际上就是确定调用该线程函数的入口点, 在线程创建后,就开始运行相关的线程函数。函数,让线程显式退出,这是线程的主动行为。

2025-12-09 14:52:56 1047

原创 外设与接口:input子系统

如按键、键盘、触摸屏和鼠标等输入设备的驱动方式是类似的,当出现按键、触摸等操作时,硬件产生中断,然后 CPU 直接读取引脚电平,或通过 SPI、I2C 等通讯方式从设备的寄存器读取具体的按键值或触摸坐标,然后把这些信息提交给内核。使用 input 子系统 驱动的输入设备可以通过统一的数据结构提交给内核,该数据结构包括输入的时间、类型、代号以及具体的键值或坐标,而内核则通过 /dev/input 目录下的文件接口传递给用户空间。字段,找到想要控制的设备,记下设备对应的。),编写程序需要用到。

2025-12-09 14:51:13 282

原创 外设与接口:IIO的使用

IIO(Industrial I/O)子系统是 Linux 内核中的一个重要组成部分,专门用于处理各种工业和嵌入式应用中的模拟输入和输出设备。IIO 子系统的主要目标是提供一个通用的、统一的框架,以便在 Linux 中支持各种不同类型的模拟设备。IIO 子系统通过 sysfs 文件系统和用户空间提供了统一的接口,允许用户轻松地访问和配置模拟设备。目录中,包含了与系统中检测到的 IIO 设备相关的子目录。每个设备子目录中包含了一组属性文件,这些文件用于获取和配置 IIO 设备的各种参数和状态。

2025-12-09 14:46:16 726

原创 外设与接口:UART的使用

随着时间的推移,TTY 的概念也扩展到串口设备,如ttyn、ttySACn等。在 Linux 系统中,终端设备的支持非常强大,它们通常通过特殊的设备文件进行访问和控制,从而实现串口通信。两个宏定义的宏值都为1,表示支持c_ispeed和c_ospeed表示方式, 部分标准中不支持使用这两个结构体成员表示波特率,而只使用c_cflag来表示。目录中,每个 UART 设备都有其自己的目录,这些目录的名称是 ttyS 加上串口号,:这是较新的标准引入的成员,用于支持更高的或分离的波特率。

2025-12-09 14:41:29 737

原创 外设与接口:SPI的使用

在 Linux 操作系统中,SPI 子系统是一个关键的驱动框架,用于管理和控制通过 SPI 总线连接的各种外部设备,有关 SPI 子系统的更多详细信息可以在。SPI 是全双工的,发送一个字节的同时,必然会接收一个字节。可以利用这个特性进行自测,用一根杜邦线,将SPI3 的 MOSI 和 MISO 引脚短接。在编写应用程序时需要使用ioctl函数设置spi相关配置,其函数原型如下。用户GPIO中引出了一组SPI接口(SPI3)。代表 SPI 总线号(Bus 3),查看设备节点,应该看到类似。

2025-12-08 09:09:44 926

原创 外设与接口:I2C的使用

在 Linux 操作系统中,I2C 子系统是一个关键的驱动框架,用于管理和控制通过 I2C 总线连接的各种外部设备,有关 I2C 子系统的更多详细信息可以在。Linux 提供了一套 I2C 调试工具 i2c-tools。用户GPIO中引出了两组I2C,分别是I2C2与I2C3。通过以下程序,可以实现 i2c-2 总线上的设备扫描。

2025-12-08 09:07:03 910

原创 外设与接口:使用libgpiod操作GPIO

libgpiod是 Linux 官方提供的用于与 GPIO 字符设备()交互的 C 语言库。自 Linux 内核 4.8 起,它替代了旧的 sysfs 接口(),提供了更安全、高效、线程安全的 API,支持事件驱动、多引脚操作等高级特性。

2025-12-08 09:05:03 1392

原创 外设与接口:PWM的使用

在成功导出 PWM 的一个通道后,会在该 PWM 的设备目录下生成单个通道的目录,其中有这个通道对应的属性文件,用户可以通过修改这些文件的内容来配置和控制特定 PWM 通道的各个参数,以实现对 PWM 信号的精确控制。PWM,全称为脉冲宽度调制(Pulse Width Modulation),是一种通过控制信号的脉冲宽度来实现模拟信号输出的技术。的形式命名,其中 X 是 PWM 设备的编号。其中,pwmchip1对应PWM8_M0,pwmchip2对应PWM9_M0,pwmchip3对应PWM14_M0。

2025-12-08 09:00:33 738

原创 外设与接口:GPIO的使用

当导出一个 GPIO 引脚时,内核会动态创建相应的目录和文件,以便用户空间程序可以访问和控制该引脚。,每次对文件执行写入操作时,会触发驱动代码,使用这次写入的内容作为参数来修改 gpio101 的引脚电平;在将 GPIO 引脚导出到用户空间时,通常需要用到引脚编号,可以通过接口图进行确定,如 18 号引脚的引脚名称为 GPIO3_A5,引脚编号为 101。导出到用户空间是指将内核空间中的资源(如 GPIO 引脚、设备状态等)通过某种机制暴露给用户空间程序,使得用户程序可以访问和控制这些资源。

2025-12-05 09:16:15 925

原创 泰山派解决pip安装报错:is not a supported wheel on this platform

其中有一个(‘cp37’, ‘cp37m’, ‘linux_aarch64’)对应要安装的python3.7版本的whl,那么whl文件中应该是linux_aarch64而不是manylinux_2_17_aarch64.manylinux2014_aarch64,所以将文件名改成rknn_toolkit_lite2-2.3.2-cp37-cp37m-linux_aarch64.whl,然后再进行安装,结果安装成功。下载的包不符合所在的平台的安装whl的名称规范,所以出错。

2025-12-05 08:57:43 378

原创 GCC编译

在同一平台上完成编译,生成的可执行文件直接在本机环境运行。

2025-12-05 08:55:00 674

原创 容器内调用QEMU运行程序找不到运行时库

交叉编译工具链在安装时,其实已经准备好了目标平台(ARM64)的所有库和链接器。它们被打包在一个叫做 sysroot。为了让每次启动的容器都自动配置好这个环境,可以把它写进 Dockerfile。可以通过设置环境变量,让 QEMU 自动去这个路径找库。(系统根目录)的地方。只需要告诉 QEMU 去哪里找它就行。) 是 x86_64 架构的 Ubuntu。这个环境变量在当前容器会话中一直有效。修改 Dockerfile,在。这次,程序应该就能成功运行了。对于 Ubuntu 上通过。容器,其根文件系统 (

2025-12-05 08:46:53 526

原创 为宿主机注册QEMU解释器

编译出了一个 ARM64 架构的程序,但运行它的环境试图让宿主机的 x86_64 CPU 直接执行它,这当然会失败。的设置,设置好后,所有的容器都能受益。这是最简单、最可靠的方法,不依赖宿主机是什么 Linux 发行版。当内核看到一个它不认识的二进制文件(比如 ARM64 的)时,它会自动调用。当这个容器执行完配置并退出后,这些规则已经被写入了宿主机的内核。如果宿主机是 Ubuntu 或 Debian,也可以直接安装。来“翻译”并执行这个程序。包,它通常会自动完成注册。),就说明注册成功了。

2025-12-05 08:43:51 481

原创 使用Docker配置适配泰山派的交叉编译环境

基于一个干净的 Ubuntu 镜像,手动安装所需的工具链。在项目目录下,创建一个Dockerfile文件。输出应该类似这样,明确指出是。

2025-12-04 12:14:32 357

原创 Docker基础使用

在开发阶段,不需要每次都 Build,可以创建一个 GCC 环境作为开发环境,并把宿主机的文件夹映射到容器里。实现在本地改代码,Docker 里编译程序,而且这个程序直接出现当前目录下。指令不仅仅是引入一个基础镜像,它实际上是开启了一个全新的构建阶段。第一阶段用大体积的编译镜像生成可执行文件,第二阶段只把最终的可执行文件复制到一个干净、小巧的运行镜像中。在使用非root用户输docker命令需要sudo,在 Linux 中,可以把当前用户加入。因为官方下架了dockerhub的镜像,更换一个阿里的镜像源。

2025-12-04 12:11:59 570

原创 在Ubuntu中配置适配泰山派的交叉编译环境

上述命令编译得到的可执行程序 hello 可以在 Ubuntu 中运行,但是如果把它放到泰山派上去,它是无法执行的。因为它是使用 gcc 编译的,是给 PC 机编译的,里面的机器指令是 x86 的。从官网下载软件包后(以gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu为例),要将交叉编译工具的路径添加到系统的。环境变量中,以便可以在任何地方使用交叉编译工具,可以在shell配置文件中添加以下行(通常是。,具体取决于使用的shell),注意。

2025-12-04 12:10:27 429

原创 Linux常用指令“ls -al”及其输出拆解

含义:文件内容最后一次被修改的时间。注意:对于目录,这个时间指的是目录内容(即文件列表)发生变化的时间,比如在其中创建、删除、重命名了文件。Linux实际上有三种时间戳,ls -l默认显示的是mtime。可以使用命令查看所有三个时间戳。mtime(modification time): 内容修改时间。atime(access time): 最后访问时间(读取文件内容会更新)。ctime(change time): 元数据修改时间(比如修改权限、所有者、文件名等)。

2025-12-04 12:07:43 721

原创 泰山派连接WiFi和安装SSH

ifconfig 查看网络状态,ping baidu.com, 测试OK。会列出所有已保存的连接,包括WiFi名称(NAME列)。ps:手机热点要将频段设为2.4GHz。直接nnmcli命令连接WIFI。使用SSH工具进行连接(

2025-12-04 12:03:04 687

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除