自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 瑞芯微 RK3588 与 NVIDIA Jetson 开发板上的 YOLOv5 端侧部署实践与对比:从 PyTorch 到 RKNN / TensorRT

YOLOv5 是端侧视觉项目中非常常见的目标检测模型。它训练方便、模型结构清晰、部署资料多,适合作为边缘 AI 部署入门和求职项目。Ultralytics 官方 YOLOv5 仓库说明,YOLOv5 基于 PyTorch,常用于目标检测、分割和分类等视觉任务,并提供了训练、测试和部署相关文档。在实际工程中,同一个 YOLOv5 模型部署到不同硬件平台时,部署链路差异很大。

2026-05-02 15:44:27 8

原创 Linux内核与驱动:14.SPI子系统

在现代嵌入式系统开发中,SPI(Serial Peripheral Interface)总线因其全双工、高速率的特性,成为了连接各类外设(如 CAN 控制器、OLED 屏幕、各类传感器)的绝对主力。然而,面对复杂的 SoC 内部资源和多任务的操作系统,如果让每一个外设驱动都直接去操作 CPU 物理底层的寄存器,代码将变得极度臃肿且难以移植。为了解决这个问题,Linux 内核引入了。它完美贯彻了“总线-设备-驱动”的分层隔离模型,将繁杂的硬件时序与纯粹的业务逻辑彻底解耦。

2026-04-30 15:49:25 417

原创 Linux内核与驱动:GPIO设备树与SPI设备树的区别

首先先看SPI的整体应用-内核-硬件的框架:在硬件层我们可以看到存在SPI控制器和SPI外设,而我们一般操作的是外设,所以写的驱动也是外设的驱动,而SPI控制器连接的是SPI适配器的驱动层,这部分驱动是由芯片原厂工程师进行编写的。我们本篇文章描述的是设备树的写法,我们知道设备树描述的是由图可知,对于SPI来说,或者说对于我们要编写一个SPI外设来说,具有两个硬件设备,一个是SPI控制器,一个是SPI外设,一般情况下SPI控制器的设备树是原厂工程师写好了的,所以我们一般只需要自己写SPI外设的设备树即可。

2026-04-27 22:47:05 380

原创 Linux内核与驱动:13.从设备树到Platform平台总线

上两篇博客描述了一些设备树的基础知识和一些简单常见的设备树撰写,然而撰写设备树的很大一部分目的是用于代替平台总线Platform的 device 部分。所以,这篇文章我们讲述这些设备树节点最终是怎么进入 Linux 驱动模型的,设备树是怎样代替 device.c 的。

2026-04-18 23:38:33 393

原创 Linux内核与驱动:12.设备树实例分析

本篇文章介绍一些基础的设备树实例分析,包括等内容,逐一拆建这些设备常见设备树形式,做到读懂,会改。

2026-04-14 22:44:26 460

原创 Linux内核与驱动:11.设备树

在设备树出现之前,ARM 架构下的 Linux 开发曾面临一个严重的困境:硬件信息被硬编码在 C 源码中,每块电路板都需要定制独立的内核,导致内核镜像泛滥,维护成本极高,这与 Linux“一内核多平台”的目标严重冲突。设备树的本质,就是一种树状数据结构,用于描述硬件平台上那些不能动态探测到的设备(如 CPU、内存、片内外设等)。它将硬件信息从内核源码中分离出来,保存在独立的配置文件中,内核启动时动态读取这些信息,自动加载适配驱动。

2026-04-14 12:48:44 411

原创 Linux内核与驱动:10.平台总线platform

platform 是 Linux 内核中一种虚拟总线机制,主要用来管理那些片上外设或不依赖真实可枚举总线的设备。它和 I2C、SPI、USB 不一样。有总线协议有设备挂接关系有设备发现或通信机制把“设备信息”描述出来把“驱动”注册进去然后由内核完成匹配和绑定platform 是 Linux 为“板级设备、SoC 内部设备、片上资源型设备”设计的一种驱动管理框架。

2026-04-12 19:43:01 691 1

原创 Linux内核与驱动:9.中断

中断,简单来说就是硬件设备向 CPU 发出的“我有事情要处理”的信号。当外部设备(如按键、网卡、定时器等)有数据需要 CPU 处理时,会通过中断控制器向 CPU 发送一个中断请求。CPU 接收到信号后,会暂停当前正在执行的任务,转而执行与该中断对应的中断处理函数,处理完毕后再恢复之前的任务。

2026-04-11 19:43:38 433 1

原创 Linux内核与驱动:9.Linux 驱动 API 封装

很多人在写完 Linux 字符设备驱动后,应用层都是直接调用:open(),read(),write(),lseek(),ioctl(),close()。这样当然能跑,但有两个问题很快会出现:第一,业务代码到处散落着 /dev/xxx、ioctl 命令号和各种系统调用。第二,一旦驱动接口改了,所有应用程序都要跟着改。更好的做法是:在用户态再封装一层 API,把驱动访问统一成几个清晰的函数。

2026-04-11 16:55:46 233 1

原创 Linux内核与驱动:8.ioctl驱动基础

fd为文件描述符,cmd为命令码,……为参数;ioctl 函数调用时,第二个参数cmd是一个 32 位的命令码,它并不是一个随意填写的整数,而是经过了精心的编码。位段位范围宽度含义方向(direction)31-302 bits数据传输方向数据大小(size)29-1614 bits传输的数据大小设备类型(type/幻数)15-88 bits驱动标识符命令编号(number)7-08 bits具体命令序号宏含义适用场景无数据方向的命令不传输任何参数的命令。

2026-04-10 20:46:03 389

原创 Linux内核与驱动:7.从应用层 lseek() 到驱动层 .llseek,Linux 字符设备偏移控制详解

很多初学 Linux 驱动的人,都会写 open/read/write/release,但一到 llseek 就容易糊涂:这篇就把这条链路完整讲清楚:从用户态 ,一路走到驱动层 lseek()本质上是在改“文件位置指针”;这行代码的含义是,把这个文件描述符的偏移量位置调整到起始位置偏移10的地方。后续无论是read还是write这个fd,都是在调整之后的位置,同样的,read/write之后偏移量也会改变。在内核里,这个“当前位置”通常对应:所以,lseek() 的核心作用,就是修改 struc

2026-04-10 13:00:32 331

原创 Linux内核与驱动:7.定时器

一个定时器。它设定了回调函数,并将其他字段(如到期时间)初始化为 0。

2026-04-08 10:31:22 183

原创 Linux内核与驱动:6.IO模型

你可以静态定义,也可以动态初始化。// 方式1:静态定义并初始化// 方式2:动态初始化。

2026-04-07 11:17:38 385

原创 Linux内核与驱动:5.并发与竞争

本文介绍了Linux驱动中的并发竞争问题及处理机制。竞争主要源于多核并发、内核抢占、硬件中断和软中断/Tasklet四种情况。重点讲解了四种并发处理机制:原子变量适用于简单计数器操作;自旋锁用于极短临界区且可中断场景;信号量允许休眠,适合长时间临界区;互斥锁是信号量的特例,适用于标准互斥访问。特别强调了驱动层与应用层在并发处理上的关键区别:驱动层需考虑中断上下文、多核并发等复杂场景,不能随意休眠,且必须使用特殊机制如自旋锁和内存屏障。文章还对比了不同场景下的最佳同步方案选择,为驱动开发者提供了实用的并发处理

2026-04-02 22:43:55 421

原创 Linux内核与驱动:4.字符设备驱动基础

摘要:本文详细介绍了Linux字符设备驱动的开发要点。字符设备通过/dev目录下的设备文件与用户空间交互,核心组件包括设备号(dev_t)、字符设备对象(struct cdev)和文件操作结构(struct file_operations)。开发流程包含:1)使用alloc_chrdev_region动态分配设备号;2)通过cdev_init和cdev_add注册字符设备;3)实现file_operations中的操作函数;4)利用class_create和device_create自动创建设备节点。文章还

2026-04-01 10:47:58 439

原创 Linux内核与驱动:3.驱动模块传参,内核模块符号导出

Linux内核提供了三种内核传参的宏定义,分别是module_param(name, type, perm)、module_param_array(name, type, nu mp, perm)宏和module_param_string(name, string, len, perm)宏,分别进行基本类型、数组和字 符串参数的传递。它们定义在“内核源码/include/linux/moduleparam.h”文件中。name: 变量名。type: 参数类型(如int,bool,char等)。perm。

2026-03-30 20:31:49 401 1

原创 Linux内核与驱动:2.驱动基础(编译驱动)

本文介绍了Linux驱动程序的开发流程,包括驱动框架、编译方法和部署方式。主要内容涵盖:1)驱动程序的基本结构,包含模块加载/卸载函数、许可证声明等必要组成部分;2)编译前的准备工作,包括内核版本匹配、交叉编译工具链配置;3)两种编译方式:通过Makefile生成可加载模块(.ko),或通过menuconfig将驱动编译进内核(built-in);4)模块的加载卸载命令(insmod/rmmod/modprobe)及调试方法。文章提供了完整的代码示例和配置说明,重点区分了模块化和内置编译的特点及适用场景,为

2026-03-30 15:44:58 372

原创 Linux内核与驱动:1.编译Linux源码

本文介绍了在Ubuntu虚拟机环境下编译RK3568开发板Linux系统的完整流程。主要内容包括:1)系统源码的四个组成部分(u-boot、kernel、recovery和文件系统);2)两种编译方式(单独编译和整体编译);3)具体编译步骤,包括选择屏幕接口配置、单独编译各组件(u-boot、kernel、recovery、buildroot)的方法;4)镜像打包生成update.img的过程;5)自动化编译选项的使用说明。文章以buildroot文件系统为例,详细说明了从源码准备到最终镜像生成的全过程操作

2026-03-30 11:43:29 358

原创 深度解析C++线程池(模型推理)

本文介绍了线程池的基本概念及其在并发编程中的重要性。线程池通过预先创建和管理线程,避免了频繁创建/销毁线程的开销,能有效控制并发数量并提高响应速度。文章结合YOLOv5推理任务的C++实现,详细解析了线程池的核心架构,包括线程初始化、任务提交、工作线程处理和结果回收等关键环节。通过任务队列和条件变量机制,实现了线程的有序管理和任务的高效执行。线程池的核心价值在于使并发变得有序、可控,在提高系统性能的同时确保稳定性,是工程实践中不可或缺的重要技术。

2026-03-29 16:28:00 348

原创 V4L2采集链路解析:从摄像头到用户态图像

V4L2是Linux内核的视频采集框架,提供统一API管理摄像头设备。通过/dev/videoX节点访问,支持RGB、YUYV等像素格式和MJPEG、H.264等编码格式。编程流程包括:1)打开设备;2)设置格式;3)通过mmap映射缓冲区;4)启动采集流;5)使用QBUF/DQBUF循环处理数据。V4L2采用内核-用户空间协作模式,通过ioctl命令(如VIDIOC_S_FMT、VIDIOC_REQBUFS)控制硬件,简化了驱动开发和应用层交互。核心机制包括缓冲区队列管理和内存映射,实现高效视频流处理。

2026-03-24 15:33:15 398 1

原创 Linux系统下文件I/O(标准库)基础操作讲解

摘要:本文介绍了Linux中"一切皆文件"的核心概念,详细讲解了标准I/O库的文件操作函数。主要内容包括:1)使用fopen打开文件获取FILE指针;2)写入文件的三种方式(fputc、fputs、fprintf);3)读取文件的两种方法(fgetc/fgets、fscanf);4)标准输入输出流(stdin/stdout/stderr)的使用。强调所有文件操作都基于FILE指针而非文件名,并提醒操作完成后需用fclose关闭文件。

2026-03-22 15:41:58 363

原创 从“标准 IO”走向“系统调用”

本文探讨了Linux系统中标准IO与系统调用的关系。标准IO库(如fopen/fputs)通过FILE*指针操作文件,但内核实际只识别文件描述符(fd)。系统调用是应用程序请求内核服务的标准方式,文中重点介绍了文件操作相关的系统调用:open()用于打开文件并返回fd,read()/write()进行读写操作,close()关闭文件描述符。理解系统调用是掌握Linux文件操作本质的关键,因为所有标准IO最终都要通过系统调用与内核交互。正确使用这些系统调用能避免资源泄漏等问题。

2026-03-06 17:32:35 1065

原创 进程处理——fork(),execve()等系统调用

本文介绍了进程的基本概念及相关操作函数。进程是程序加载到内存运行后的实例,是操作系统资源分配的基本单位。文章详细讲解了进程处理相关函数:获取进程ID(getpid/getppid)、创建进程(fork/execve)、进程退出(exit/_exit)以及进程回收(wait/waitpid)。重点区分了fork和execve的功能差异,并解释了父进程回收子进程的必要性,以避免产生僵尸进程。通过系统调用和库函数的对比,说明了不同退出方式的清理机制差异。

2026-02-09 17:24:00 1100

原创 一文搞懂 Linux 进程通信:从 pipe 到 消息队列

本文介绍了进程间通信(IPC)的几种主要方式:管道通信(匿名管道pipe和有名管道fifo)、共享内存和消息队列。管道通信利用内核缓冲区实现数据传递,匿名管道限于亲缘进程,有名管道则可通过特殊文件实现非亲缘进程通信。共享内存通过直接访问同一内存区域实现高速数据传输,避免了内核中转。消息队列以异步方式发送和接收数据,支持优先级设置。文章详细说明了各种通信方式的创建、使用方法和特点,并指出管道通信占用内核空间的劣势,以及共享内存的高效性。最后提到socket通信将另文详述。

2026-02-09 17:23:30 1141

原创 Linux驱动:spinlock和mutex的区别

本文对比了自旋锁和互斥锁的特性与适用场景。互斥锁采用睡眠等待机制,适合较长的临界区操作,但存在调度开销;自旋锁通过忙等待避免上下文切换,适合极短临界区,但会浪费CPU资源。关键区别在于:互斥锁让出CPU,自旋锁持续占用CPU。使用场景上,自旋锁适用于中断处理、多核极短临界区,互斥锁适合I/O、复杂计算等耗时操作。两者本质是CPU时间与延迟的权衡,实际应用中可根据临界区长短选择合适的锁机制。

2026-02-06 15:03:21 944

原创 网络协议:IP,TCP详细介绍,以及应用层HTTP与RTMP的区别

本文系统解析了IP、TCP、HTTP和RTMP四大网络协议的分层协作机制。IP协议负责网络层寻址路由,提供不可靠的数据包传输;TCP在传输层通过三次握手、滑动窗口等机制实现可靠连接;HTTP作为应用层协议支撑万维网通信,经历1.1到3代的性能优化;RTMP专为实时音视频设计,采用持久连接和分块传输实现低延迟直播。这些协议通过分层解耦的设计理念,共同构建了现代互联网的基础架构,满足从网页浏览到实时直播的多样化需求。

2026-01-15 11:06:39 1119

原创 易语言高级编程技巧:性能与扩展性突破

本文介绍了易语言高级编程技巧,重点解决单线程卡顿、代码复用差等问题。主要内容包括: 多线程开发:通过"餐厅运营"类比解释多线程概念,展示如何创建线程、使用临界区保护共享资源,解决界面冻结问题。 DLL开发与调用:详细说明如何封装核心业务逻辑为DLL,实现代码复用和知识产权保护,包括DLL工程创建、函数导出和调用方法。 系统升级方案:将网络版成绩管理系统升级为多线程高性能版本,支持100+客户端并发连接,界面无冻结。 错误排查:列举多线程死锁、DLL导出错误等常见问题解决方案。 文章通过生

2025-12-19 10:07:38 961

原创 【实战】嵌入式 Linux Makefile 编写指南:告别 IDE,拥抱命令行

本文是一篇嵌入式Linux开发中Makefile的实战指南。文章首先解释了学习Makefile的必要性,包括自动化构建、增量编译和交叉编译支持三大优势。然后详细介绍了Makefile的核心语法规则,包括变量定义、自动变量($@、$^、$<)的使用方法。重点讲解了如何通过定义CROSS_COMPILE变量实现交叉编译支持,并最终提供了一个通用Makefile模板,该模板支持自动扫描源文件、交叉编译和清理功能。文章建议初学者从简单入手,逐步掌握Makefile这一构建系统的基础工具,为后续学习CMake等

2025-12-10 09:54:20 1595

原创 从C语言到C++:面向对象三大特性之继承

本文介绍了鸿蒙系统开发中的网络请求与数据存储技术。主要内容包括:1)网络请求实现,涵盖权限配置、官方fetch API和第三方axios的使用;2)本地数据存储方案,重点讲解轻量级Preferences键值对存储和关系型数据库RelationalStore;3)实战项目示例,展示网络数据获取、UI渲染到本地持久化的完整流程。文章还提供了常见问题解决方案和最佳实践指导,帮助开发者快速掌握鸿蒙应用数据交互核心技能。

2025-12-08 11:00:06 1390

原创 从C语言到C++:面向对象三大特性之封装

本文介绍了C++面向对象编程的三大特性之一:封装。首先对比了C与C++的基本语法差异,如头文件和命名空间的使用。重点讲解了类的概念,包括类与对象的关系、访问权限控制(public/private/protected)及其应用场景。详细说明了构造函数(普通构造、带参构造、拷贝构造)和析构函数的特性与作用,强调它们会被自动调用的特点。通过具体代码示例,展示了如何定义类、创建对象以及使用不同权限成员的方法。文章旨在帮助有C语言基础的读者快速理解C++面向对象编程的核心概念。

2025-12-08 10:52:19 1619

原创 进程的创建与调度——fork,exec,system等系统调用/函数

本文介绍了进程的基本概念及其在操作系统中的管理方法。进程是程序在内存中运行的实例,是资源分配的基本单位。重点讲解了进程处理相关函数:获取进程ID的getpid()和getppid()、创建进程的fork()和execv()组合、进程退出的exit()和_exit()、以及进程回收的wait()和waitpid()。同时分析了三种特殊进程状态:僵尸进程(已终止但未被回收)、孤儿进程(父进程先终止)和守护进程(长期运行的后台服务)。文章通过代码示例演示了如何创建和管理进程,并提供了处理僵尸进程的解决方案。这些内

2025-12-04 10:36:13 1241 1

原创 嵌入式Linux开发中,最常用的Linux系统命令

本文总结了Linux常用命令,包括文件和目录操作(如pwd、cd、ls、cp、rm)、权限管理(chmod)、查找命令(find)、网络工具(ifconfig、ping)、远程连接(ssh)、磁盘管理(mount、lsblk)、压缩解压(tar、gzip、zip)以及进程管理(ps、top、kill)。重点介绍了各命令的常用选项,如ls -a显示隐藏文件,find按名称/大小查找文件,tar打包压缩等。这些命令覆盖了Linux系统管理、文件操作和网络配置等日常运维需求,是Linux用户必备的基础操作技能。

2025-12-04 10:31:24 1763

原创 从 0 到 1:把 Linux 线程(pthread)讲清楚

Linux线程是同一进程内的并发控制流,共享进程资源但拥有独立栈和寄存器。线程创建使用pthread_create(),需指定入口函数和参数。线程结束方式包括return、pthread_exit()或exit()。线程资源回收分为两种:joinable线程需pthread_join()手动回收,detached线程自动回收。必须对joinable线程调用pthread_join()或pthread_detach()以避免资源泄漏。

2025-12-03 12:00:09 986 3

原创 异地也能一起画图?Tldraw+cpolar 实现跨空间协作

Tldraw是一款开源免费的轻量级在线绘图工具,支持多人实时协作、无限画布和多种图形工具。本文介绍了通过Docker部署Tldraw并结合cpolar实现远程访问的方法:首先在本地安装Docker并部署Tldraw服务,然后配置cpolar将本地7900端口映射到公网,生成可远程访问的地址。此外,还展示了如何设置固定二级子域名,确保访问地址稳定不变。该方案突破了Tldraw原有的局域网限制,使团队成员无论身处何地都能通过链接实时协作绘图,特别适合远程团队协作和在线教学场景,充分发挥了Tldraw的协作优势。

2025-12-02 10:10:48 7282 115

原创 仓颉语言教程:从零实现财务数字转中文大写工具库

本文介绍了如何使用仓颉语言实现财务数字转中文大写工具库。文章详细分析了需求功能,包括支持正负数、小数转换及零的处理规则。核心算法采用分层设计,通过数学运算而非字符串操作提高性能,巧妙处理了万进制分段转换和零的特殊规则。代码实现包含主函数、整数转换和四位数段转换三个关键部分,并针对财务场景进行了优化。该方案具有O(log n)的时间复杂度和O(1)的空间复杂度,能高效处理各种边界情况。

2025-12-01 20:23:18 5629 152

原创 硬件连接的艺术:在工程与美学之间寻找完美平衡

摘要:硬件连接是技术与艺术的融合,既要确保功能性,也要追求设计美感。文章探讨了连接的基础概念、布局艺术和高级技术,包括PCB设计美学、线缆管理和高速传输优化。同时分析了故障诊断方法和未来趋势,如光连接和物联网应用。硬件连接的艺术推动着技术创新,需要持续追求功能与美学的平衡。

2025-12-01 20:06:49 6063 151

空空如也

空空如也

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

TA关注的人

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