- 博客(82)
- 收藏
- 关注
原创 用户通用驱动spidev.c与设备匹配问题
靠的是 spi_match_device 最后的字符串名称硬匹配机制(Fallback)。,但最后还是能匹配成功。
2026-01-26 01:29:27
304
原创 20260125 - Linu驱动学习笔记:SPI-OLED测试
其次是 oled_write_cmd_data,目前每写 1 字节就要切换一次 DC 引脚并执行一次 write。D/C引脚接在了GPIO4_20,即116号引脚,在APP程序中控制即可,不需要写进驱动。屏幕显示数据的速率肉眼可见地缓慢,性能太差。优化逻辑:尽量将连续的命令或连续的数据打包在一起发送。因此可直接使用内核通用SPI驱动spidev.c。目前代码中, 导致性能低的最大原因是。函数,其次是碎片化的。原函数执行了 3 次。,可以合并为 1 次。
2026-01-26 01:28:47
389
原创 内核日志分析:__spi_pump_messages的Caller_Optimization和KWorker_Thread
进入原因:第一次调用结束后,kworker被调度检查队列返回位置执行内容:关闭硬件、释放资源、电源管理延迟原因:硬件操作本身就慢(131ms)是否正常:✅ 完全正常,这是设计的省电机制。
2026-01-25 16:03:45
577
原创 20260123 - Linux驱动学习笔记SPI子系统的匹配机制深度解析
时机MasterDeviceDriver匹配函数结果系统启动spi-imx.ko加载自动创建未加载无master和device已关联已存在已存在正在注册匹配并调用probe已存在已存在已绑定无直接使用private_data已存在已存在已绑定无沿指针链调用。
2026-01-24 11:58:12
322
原创 借助通用驱动spidev实现SPI全双工通信
关键理解:这个ioctl调用的是函数:二、TLC5615 DAC芯片的工作机制2.1 芯片手册解读TLC5615是10位串行DAC,时序如下:2.2 DAC芯片的回显机制(Shift Register Echo)TLC5615的DOUT引脚行为:这是移位寄存器类DAC的标准设计:三、只发送不接收的测试3.1 纯写模式(丢弃RX数据)底层仍然在接收,只是数据被丢弃在内核的rx_buffer中。TLC5615的特性回显上次写入值是芯片的设计特性可用于写后验证(write-ver
2026-01-24 11:57:15
1031
原创 20260122 - Linux驱动学习笔记:分层与解耦
Linux 设备驱动模型(Device Model)的核心设计哲学:分层与解耦。硬件工程师在设备树里写好硬件的参数。在设备树文件中:2. 数据的搬运工:SPI Core 层 ()在系统启动(或者动态加载设备树)时,Linux 内核的 SPI 核心层会做以下几件事,这些动作发生在 被调用之前:当 SPI Core 发现 (设备) 和 (驱动) 匹配成功后,它会调用 ,并把那个已经填满了数据的结构体指针传给你。[图解] 数据流向全景为了让你看得更清楚,我为你整理了一个一一映射表,你可以直接对应查
2026-01-22 15:51:36
63
原创 Linux驱动学习:验证MasterDriverDevice三方匹配成功
检查是否存在。(对应你的日志:Master Bus Num: 0, Name: spi0)检查是否存在。(对应你的日志:find -name “oled” 找到了节点)Driver 代码{ .compatible = "100ask,oled" }, // 这里的名字{ }DTS// 必须和这里完全一致如果两者一致,内核会调用probe,然后你就能在下看到spi0.0。w。
2026-01-20 19:22:52
418
原创 20260120 - Linux驱动学习笔记:SPI子系统核心层到具体硬件驱动
步骤函数文件说明1oled_drv.c你的驱动调用2spi.cSPI 核心 API3spi.c构造消息4spi_sync()spi.c同步传输5spi.c核心同步逻辑6spi.c消息入队7spi.c处理消息队列8spi.c遍历 transfers9函数指针跳转到硬件驱动10spi-imx.ci.MX 硬件传输11spi-imx.c配置硬件12spi-imx.c写 FIFO13spi-imx.c中断处理关键点:从 SPI 核心层到具体硬件驱动的跳转是通过。
2026-01-20 19:22:10
94
原创 20260119 - 内联函数详解
*** 内联函数 - 定义在头文件中*/if (!master ||!为什么用内联函数?// 如果不用 inline,在 .c 文件中定义:// spi.c// 调用时(在另一个文件 spi-imx.c 中):// ↓// 需要函数调用:// 1. 保存寄存器// 2. 跳转到 spi.c 的代码// 3. 执行函数// 4. 返回// 5. 恢复寄存器// 开销很大!
2026-01-20 01:12:17
396
原创 20260116 - Linux驱动学习笔记:什么是段错误?
进程的虚拟内存空间划分:高地址│ 内核空间 │ ← 用户程序不能访问│ 栈(Stack) │ ← 局部变量、函数调用│ ↓ ││ ││ 未映射区域 │ ← 访问这里 = 段错误!│ ││ ↑ ││ 堆(Heap) │ ← malloc分配的内存│ BSS段 │ ← 未初始化的全局变量│ 数据段 │ ← 已初始化的全局变量│ 代码段 │ ← 程序代码(只读)低地址术语含义段错误访问非法内存地址触发信号常见原因NULL指针、野指针、越界、释放后使用用户空间。
2026-01-20 01:11:35
528
原创 Linux内核中SPI 子系统的整体架构
层次职责文件SPI 核心层消息队列管理、同步/异步传输、设备注册SPI Master驱动硬件初始化、传输实现、中断/DMA处理等SPI 设备驱动使用 SPI API 与设备通信你的oled_drv.c关键点分层设计:核心层提供统一接口,具体驱动实现硬件细节队列化传输:现代驱动推荐使用而非老式transfer内核线程在后台处理消息队列同步/异步:提供spi_sync(阻塞)和spi_async(非阻塞)两种方式。
2026-01-19 14:59:14
464
原创 Linux驱动学习笔记:SPI OLED 驱动源码深度分析
Framebuffer 驱动的本质为内核申请一段内存 (填充fb_info结构体告诉内核这段内存的属性(分辨率、位深)。用户空间看到的只是一个文件/dev/fb0,对其读写就是操作这段内存。软硬差异的适配当硬件显存结构(OLED 页模式)与软件标准(Framebuffer 线性模式)不一致时,驱动程序必须充当“翻译官”。这种翻译通常涉及复杂的位运算,计算量大,适合放在后台线程处理。并发与同步本驱动利用了内核线程kthread来实现异步刷新。虽然本例未加锁,但在生产环境中,如果。
2026-01-17 21:08:45
805
原创 Linux应用与驱动开发:mmap和内存映射
mmap物理地址是唯一的真理,但被 CPU 藏在了 MMU 后面。KVA (内核虚拟地址)是驱动在内核态用的,通过ioremap映射。UVA (用户虚拟地址)是应用在用户态用的,通过mmap系统调用请求,由驱动协助映射。是连接 UVA 和 物理地址 的桥梁。下一步实践建议:在韦东山的开发板上,你可以写一个简单的程序,利用 /dev/mem 这个系统自带的驱动节点。它已经实现了 mmap 功能。
2026-01-14 00:19:01
605
原创 Linux驱动开发:中断线程化 (Threaded IRQ)
如果你只是 toggle 一个 LED 或读取内存里的一个标志位→→使用Tasklet或直接在ISR里做。如果你需要读取 I2C/SPI 传感器、写 Flash、或者逻辑很复杂→→首选 Threaded IRQ。它是最优雅、代码量最少、调试最清晰的方案。如果你需要做一些和特定中断无关的后台杂活(如日志转存)→→使用Workqueue。
2026-01-14 00:18:18
672
原创 Linux驱动开发八股文:工作队列(Workqueue)
工作队列是 Linux 内核中断下半部(Bottom Half)的一种重要机制。它允许你将耗时的、需要等待资源或可能导致休眠的任务,从中断处理函数(ISR)中推迟到稍后的进程上下文中执行。关键特性:运行于进程上下文,可以休眠。执行主体:内核线程(如处理函数的参数是结构体本身,通常通过获取私有数据。// 这里可以休眠!任务很重(如:读取 1MB 的 Flash 数据)。需要等待(如:等待某个信号量、互斥锁)。需要延时(如:逻辑要求按键按下后等待 100ms 再读取)。
2026-01-14 00:16:55
733
原创 20260111 - Linux驱动学习笔记:异步通知
通过这组代码,可以掌握 Linux 驱动中最高级的 IO 交互方式之一。优点:APP 不需要死等,也不需要不停问,CPU 利用率极高,响应速度极快(中断级)。缺点:APP 编写稍微复杂一点(需要处理信号),且信号处理函数中不能进行太耗时的操作(类似于中断处理)。
2026-01-11 19:44:28
492
原创 20260110 - Linux驱动学习笔记:环形缓冲区与按键防丢失
在单片机开发中,你可能习惯了简单地定义一个变量。但在Linux 驱动中,环形缓冲区是处理所有流式数据(如串口、按键、触摸屏、鼠标、网络包)的标准做法。没有缓冲区:驱动只能处理“当前状态”(如:灯亮了吗?有了缓冲区:驱动可以处理“事件序列”(如:用户刚才按下了什么序列?
2026-01-11 19:42:53
457
原创 20260110 - Linux 驱动开发学习笔记:上下文、中断与休眠
要理解为什么不能在中断处理函数中里调用休眠函数让出CPU,首先必须搞清楚。
2026-01-11 19:35:43
873
原创 20260109 - Linux 内核中断子系统数据结构
结构体名抽象角色包含什么谁来写/谁提供irq_desc档案袋irq_datairqaction内核核心层 (自动管理)irqaction收件人用户处理函数 (handler驱动开发者irq_data硬件标签硬件中断号 (hwirq芯片 BSP (NXP)irq_chip工具箱硬件操作函数 (ackmask芯片 BSP (NXP)irq_domain翻译官hwirq<->virq映射表芯片 BSP (NXP)
2026-01-11 19:35:15
842
原创 20260103 - Linux总线设备驱动模型学习笔记
维度传统方式总线驱动模型代码结构硬件资源与逻辑耦合资源与逻辑完全分离可移植性差,换硬件需改源码编译强,只需更换设备端资源管理效率低,容易造成驱动代码冗余高,支持多实例匹配动作触发函数内核行为驱动层响应装载驱动找设备名并匹配匹配成功则执行probe装载设备找驱动名并匹配匹配成功则执行probe匹配逻辑执行三级匹配规则(内核自动执行)卸载逻辑解除绑定关系执行remove这是 Linux 总线设备驱动模型学习笔记的第四部分,重点解析驱动开发中频繁调用的内核 API。作用。
2026-01-04 23:08:55
828
原创 20260103 - Linux平台总线LED驱动架构深度解析
可扩展性换板子?只需重写,无需动驱动逻辑。换芯片?只需重写,无需动上层逻辑。维护性:核心层leddrv.c极其稳定,作为通用框架,一旦写好几乎不需要修改。这份笔记涵盖了从代码细节到架构设计的全部核心内容。
2026-01-04 23:08:15
1381
原创 20260102 - Linux驱动设计的思想
分层 (Layering):是纵向切割。把(给内核看的)和(给硬件看的)分开。分离 (Separation):是横向切割。在硬件操作层内部,把“资源(Resource)”和“逻辑(Logic/Driver)”彻底分开。首先,我们需要一个“协议”,规定如何描述一个 LED 硬件资源。// 定义描述硬件资源的结构体int group;// GPIO组号,例如 1 代表 GPIO1int pin;// 引脚号,例如 3 代表 GPIO1_3// 获取资源的函数声明左边是(变化的部分)这里全是。
2026-01-04 23:07:44
941
原创 20251230 - 为什么Linux驱动开发中必须要用到ioremap来访问硬件?
不能直接用的原因:开启 MMU 后,CPU 硬件机制决定了所有指令中的地址都会被解读为虚拟地址。直接用物理地址会被指引到错误的内存位置或导致异常。ioremap的作用:它是连接“虚拟世界”(代码)和“物理世界”(硬件)的桥梁,负责建立映射关系。这就是为什么嵌入式 Linux 驱动开发比单片机麻烦一点的原因——你必须遵守操作系统的内存管理规则。
2026-01-02 01:44:36
381
原创 20251230 - I.MX6ULL中通用寄存器名称含义及引脚定义
(在安全管理部) —SW_PAD_CTL(用软件控制引脚电气属性) —(针对 TAMPER3 这个物理引脚)。英文缩写中文含义驱动 LED 时的典型配置建议SRE信号坡度0 (Slow)DSE劲儿大不大110 (标准驱动力)SPEED最高频率10 (100MHz 足够)ODE开漏模式0 (推挽)PKE/PUE是否用电阻1 (启用)PUS上/下拉方向10 (100K 上拉)HYS消抖使能0 (关闭)
2026-01-02 01:43:23
942
原创 20251229 - 驱动程序是如何向Linux内核注册(Register)自己的
是管理层。负责让驱动程序和设备树里的硬件描述**“对上号”**。它让驱动更灵活、更通用。:是业务层。负责实打实地生成用户接口。关系:通常在的probe函数中,去调用。前者是壳,后者是核。
2025-12-29 17:51:43
865
原创 20251228 - Linux 驱动开发硬件管理机制笔记
DTS是这张图的“地形描述是“匹配中介Probe是驱动“上岗点火”的瞬间。ioremap是在内核里“开辟秘道”直达寄存器。fops是给应用层留下的“交互窗口。
2025-12-29 17:50:57
708
原创 20251228 - Linux用户层打开字符设备节点时内核空间创建的struct file
是动态的:每次open都会产生一个新的,用于隔离不同进程(或同一进程多次打开)的读写状态。inode是静态的:文件/设备在磁盘或系统里只有一份inode。指向inode。桥梁作用:对于字符设备,充当了用户层fd和底层驱动cdev之间的桥梁。灵魂在 f_op:打开普通文件,f_op让 CPU 去读磁盘;打开字符设备,f_op让 CPU 去读写你的驱动代码。
2025-12-28 21:58:03
1215
原创 20251228 - Linux 驱动文件 (.ko) 深度解析笔记
从文件格式上讲,.ko 文件本质上是一种 ELF (Executable and Linkable Format) 文件。它和你在 Ubuntu 上看到的 .o 文件(目标文件)非常像,但多了一些“自我介绍”的信息(比如它支持哪个版本的内核、它的依赖关系等),专门用于让内核加载器识别。.ko是什么:Linux 的动态链接库,相当于 Windows 的.dll。编译前提:必须指定内核源码路径,不能用普通 GCC 编译。insmod原理搬运:把文件搬到内存。改地址:告诉驱动它住在内存哪里。找帮手。
2025-12-28 21:57:31
976
原创 20251227 - Linux用户层打开文件时内核空间会新建file结构体
理解这个过程的关键在于理清一对多进程 : files_struct= 1 : 1= 1 : N (一个进程可以打开多个文件)= N : 1场景A:进程 A 打开文件test.txt,进程 B 也打开test.txt。结果:两个不同的fd,两个不同的(各自有自己的读写偏移量f_pos),但它们指向同一个。这就是为什么当 APP 打开文件时,内核必须创建一个新的,而不是直接使用inode的原因——为了隔离不同打开者的状态(如读写偏移量)。
2025-12-28 21:57:00
545
原创 20251224 - 嵌入式 Linux 开发中的MQTT指南
是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议。它构建于 TCP/IP 协议之上。一句话概括:它是物联网界的“快递系统”。设备不需要直接对话,而是通过一个中转站(Broker)来交换信息。核心特点:极轻量(代码量少、带宽占用极低)、低功耗、适合网络不稳定的环境(如无人机通信、移动网络)。特性传统 Socket / HTTPMQTT对你的价值带宽协议头大,包含大量无用元数据最小仅 2 字节头无人机远距离传输通常带宽受限,MQTT 更省流量。连接。
2025-12-24 22:01:34
1003
原创 20251222 - 韦东山Linux开发板I.MX6ULL连接无线WiFi
执行上述脚本的前提是开发板已经连接好WiFi天线了。不一定需要连接路由器,也可以连手机热点等等。下面为您进行,最后给出。
2025-12-23 20:13:16
694
原创 20251222 - 轻量级通信协议 JsonRPC
哪怕这个函数不在我这台机器(或这个进程)的内存里,我也能像调用本地函数一样调用它。本地调用:你在main.cpp里写,程序直接跳转到那个内存地址执行。RPC调用前台(顾客):想吃“宫保鸡丁”(想执行),前台也算是一个进程。后台(厨师):在厨房里(另一个进程),前台(顾客)进不去。RPC机制:前台写一张单子塞进窗口,后台拿到单子,做好菜,再把菜(结果)递出来。错觉:对前台来说,感觉就像自己直接让菜变出来了一样,实际上是别人代劳的。JSON 就是上述那张“单子”的书写格式。
2025-12-23 20:12:33
1069
原创 20251202 - Linux输入子系统支持的操作机制
机制描述比喻CPU 占用响应速度推荐指数阻塞死等在门口一直站着等快递,直到快递来低 (睡觉)快⭐⭐⭐ (简单任务)非阻塞轮询每秒开门看一次快递来了没极高(空转)取决于轮询间隔⭐ (不推荐单独用)POLL多路复用让保安看着门口,快递来了叫醒我低 (睡觉)快⭐⭐⭐⭐⭐ (最推荐)异步信号我去打游戏,快递员到了打我电话低最快⭐⭐ (逻辑复杂)先写阻塞版本,理解。一定要掌握 poll版本,因为这是实现一个真正的嵌入式程序(比如同时处理串口指令和触摸屏操作)的基础。
2025-12-23 20:11:21
889
原创 20251202 - Linux输入子系统
输入子系统是为了统一各类输入设备的接口。核心结构体是(时间、类型、代码、值)。核心流程:硬件 -> 驱动 -> Core -> Handler (evdev) -> APP。调试:先用找设备,再用evtest抓数据。
2025-12-22 20:18:42
890
原创 20251202 - Linux输入系统的基础知识 - tslib
是一个运行在用户空间(User Space)的开源中间件库。硬件:触摸屏驱动:I2C/SPI 驱动Input Core:内核核心层Handler (分流)–> evdev(校准/去噪) -->Qt/APP(最终使用)(这是现在的标准路径)–>mousedev) --> 旧式程序–>kbd--> 终端控制台 (TTY)
2025-12-22 20:17:24
907
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅