- 博客(78)
- 收藏
- 关注
原创 Linux驱动学习day26天(RS485)
通过芯片将232信号转换成485信号,485表示0和1的方法:Va - Vb 的电压差在2~6V时表示1,Va - Vb 的电压差在-2~-6V时表示0。这样传输不容易受到干扰,并且传输距离长。我们需要做的事情就是发送:使能DE(driver enable),接收:使能nRE(设置为低电平,recive enable)。半双工方式进行通信,AB在同一时刻,要么只能发要么只能收。
2025-08-08 14:24:44
207
原创 Linux驱动学习day25天(UART子系统)
从上到下,串口驱动主要包括TTY-IO层(tty-io.c),行规程(n_tty.c),UART核心层(serial_core.c)和硬件相关的UART_driver层。一般能够使用Linux的板子上述都已经写好了代码,调试的时候在 UART_driver进行调试,编写虚拟的UART驱动程序可以更好的理解上一天的理论知识,其次虚拟的UART驱动程序可以简化硬件操作。
2025-08-07 17:49:47
943
原创 Linux驱动学习day24(UART子系统)
摘要:本文系统介绍了UART串口通信原理及Linux系统中的TTY框架。首先阐述了UART的硬件特性,包括波特率计算、数据传输流程和电平转换;其次分析了Linux TTY子系统架构,解释终端设备节点差异;然后详细讲解了串口应用编程方法,包括行规程设置和GPS数据解析实例;最后深入剖析了UART驱动框架,包括注册过程、数据收发流程及调试方法。全文通过理论分析与代码实例相结合的方式,全面呈现了Linux环境下串口通信的完整技术体系。
2025-07-18 22:57:54
976
原创 Linux驱动学习day23(依旧是interrupt子系统)
本文分析了Linux内核中断子系统中的GICv3中断控制器实现,重点探讨了链式和层级两种中断控制器处理流程。通过源码分析展示了GICv3如何通过IRQCHIP_DECLARE宏自动初始化,详细介绍了irq_domain在管理虚拟与硬件中断号映射中的核心作用。文章还提供了两种中断控制器驱动程序的实现方法(legacy和linear),比较了它们在处理中断时的差异:链式需分辨中断源而层级直接处理。最后给出了中断调试方法和实际编码示例,包括设备树解析、中断屏蔽/使能等关键操作,为理解Linux中断机制提供了实践参
2025-07-17 09:20:18
792
原创 Linux驱动学习day22(interrupt子系统)
本文介绍了ARM架构中的中断和异常处理机制,重点分析了通用中断控制器(GIC)的工作原理。主要内容包括:1. ARM异常处理流程,涉及中断初始化、执行和处理;2. GIC的功能模块和中断状态管理,如分发器(distributor)和CPU接口的作用;3. 新旧内核版本的中断处理差异,特别是虚拟中断号映射机制;4. GIC关键数据结构及其在中断处理流程中的应用。文章详细阐述了中断从触发到处理的完整过程,包括优先级判断、状态转换和异常向量表等核心概念,为理解ARM中断系统提供了系统性的技术解析。
2025-07-11 23:06:19
810
原创 Linux驱动学习day21(GPIO子系统)
管理GPIO,既能支持芯片体身的GPIO,也能支持扩展的GPIO。提供统一的、简便的访问接口,实现:输入、输出、中断。设备树中会有节点对应着GPIO控制器,里面含有cell属性,cell属性的意思是,以后如果使用到本组的GPIO,除组别之外还需要两个参数描述这个引脚。
2025-07-10 23:17:52
684
原创 Linux驱动学习day20(pinctrl子系统驱动大全)
本文介绍了Linux内核中Pinctrl子系统的作用和实现原理。Pinctrl主要用于引脚枚举命名、复用和配置,由芯片厂商BSP工程师编写驱动。文章详细分析了Pinctrl的核心结构体pinctrl_desc和pinctrl_dev,以及设备树解析流程。通过RK3568芯片案例,展示了如何从设备树转换到pinctrl_map的过程。最后提供了一个虚拟Pinctrl驱动程序的实现示例,包括设备树节点定义和驱动程序代码,重点阐述了如何分配设置pinctrl_desc结构体并实现引脚复用、配置等功能。文章指出Pi
2025-07-09 22:56:27
907
原创 Linux驱动学习day19(input子系统及扩展固定设备节点)
本文介绍了Linux输入子系统的驱动开发框架与实现方法。输入子系统采用统一的事件处理机制,通过input_dev和input_handler的匹配实现设备与驱动的连接。主要内容包括:1)输入子系统框架解析,包括设备注册、事件上报流程;2)以触摸屏驱动为例,详细说明input_dev结构体设置、中断处理和事件上报的实现;3)通过GPIO模拟按键的完整驱动实现示例;4)总结事件上报机制和开发要点。输入驱动开发的核心是正确配置input_dev的事件类型和参数,并在中断处理中通过input_event()上报事件
2025-07-08 14:46:52
1019
原创 Linux驱动学习day18(I2C设备ap3216c驱动编写)
本文介绍了AP3216C传感器的I2C驱动实现及Linux内核中的I2C驱动框架。主要内容包括:1)AP3216C驱动通过i2c_smbus接口读取16位数据并拆分为高低8位;2)Linux I2C子系统核心结构体i2c_adapter和i2c_algorithm,重点实现master_xfer传输函数;3)GPIO模拟I2C控制器的方法及其局限性;4)内置I2C控制器的中断处理机制。文章详细展示了从字符设备注册到I2C通信的完整驱动实现,包括设备树配置、数据传输处理等关键环节,为嵌入式Linux设备开发提
2025-07-06 23:10:10
1163
原创 Linux驱动学习day17(I2C驱动)
I2C 协议可以形象地比作“老师带学生踢足球”。老师就像 I²C 总线中的主设备(Master),学生则是从设备(Slave),足球代表数据,老师的口令相当于时钟线(SCL),而学生传球的动作就像数据线(SDA)上的数据传输。每次通信开始时,老师先吹哨表示“开始”,就像 I²C 的起始信号(Start);接着老师喊出某位学生的编号,比如“1号学生”,表示要与哪个从设备通信,这对应于发送设备地址;学生听到后回应“到!”,就像从设备发出的应答信号(ACK)。
2025-07-06 10:32:56
791
原创 Linux驱动学习day16(LCD驱动皮毛,之后还需重新回来学习)
本文分析了8080接口和TFT-RGB接口的LCD驱动实现。8080接口通过WRX信号线控制数据写入时序,配合data/cmd信号区分命令与数据。TFT-RGB接口采用同步模式,通过DCLK、HSYNC、VSYNC等信号实现图像同步传输。详细介绍了Linux内核中LCD驱动的实现流程:分配/设置/注册fb_info结构体、配置GPIO背光控制、获取时钟参数、从设备树解析显示时序。重点讨论了单缓冲区的缺陷及双缓冲区的实现方法,通过ioctl设置yoffset值实现缓冲区切换,避免显示撕裂现象。驱动代码展示了如
2025-07-03 23:13:02
769
原创 Linux驱动学习day15(LCD驱动)
用红绿蓝来表示,可以使用24位,也可以使用16位等等格式。bpp:bits per pixel, 用多少像素位来表示24bbp:实际上会用32位,其中8位未使用,用24位来表示,8位R,8位G,8位B16bbp:有rgb565,rgb555。
2025-07-03 08:34:40
653
原创 Linux驱动学习day14(锁)
Linux内核提供了很多锁,基本可以分为两种1、自旋锁 2、休眠锁。1、自旋锁:无法获得锁时,不会休眠,一直循环等待。解决多CPU中互斥的访问临界资源。(spin_lock(原子变量实现) , 在这个锁执行期间,会禁止别的进程调度 preempt disable禁止抢占)2、休眠锁:无法获得锁的线程会先休眠,等待锁被释放。
2025-07-02 10:32:45
163
原创 Linux驱动学习day13(同步与互斥)
需要使用特殊指令(ldrex/strex实现互斥访问)的时候需要使用内联汇编。下图是内联汇编的语法。__asm__ 冒号之前的使用" "括起来的是汇编代码,下面这个例子只有一条汇编指令。下面这段代码的意思是把第1个操作数和第2个操作数累加起来放到第0个操作数。最后一行代表除了上面那些寄存器之外还影响着什么寄存器。cc代表flags register。“r”(a)表示将a的值放入r这个寄存器中。“=r”(sum)表示这个寄存器的值会被放在sum这个变量中。
2025-07-01 23:00:52
657
原创 Linux驱动学习day12(mmap)
应用程序不能直读写驱动程序中的内容,如果需要应用程序读写,一般使用copy_to_user/copy_from_user这些内核提供的函数,在传输数据大的时候,使用这种方式就不太可行,比如更新LCD ,假设LCD采用1024*600*32bpp格式,那么每一帧就有1024*600*32/8 = 2.3MB。为了改进上述不足,可以通过mmap实现让应用程序直接修改驱动程序的buf,提高效率。
2025-07-01 15:49:40
701
原创 Linux驱动学习day11(定时器)
定时器主要作用就是:设置超时时间,执行超时函数。按键按下存在抖动,为了消除抖动可以设置定时器,如上图所示,按下一次按键会产生多次抖动,即会产生多次中断,在每次中断产生的时候,设置定时器,定时器时间是当前时间+超时时间,这样每次中断产生都会重新设置定时器时间,等到按键不抖动稳定的时候,就不会再改变定时器时间,这时候我们再记录按键值,就很稳定了。
2025-06-30 20:11:58
919
原创 Linux驱动学习day10(驱动程序的基石)
中断上下文中不可以休眠,原因是系统的进程线程调度依赖于定时器中断,如果休眠了就无法调动定时器中断,这样系统就会卡崩溃。进程/线程上下文可以休眠,调用耗时间的函数。代码核心weak_event_xxx(wq , event) wake_up_xxx(wq)两个函数,步骤如下:1、初始化wq等待队列2、休眠时wait_event_xxx(wq , event),当event = 0/false,休眠,当event= 1/true 唤醒。3、唤醒wake_up_xxx(wq)
2025-06-30 10:12:56
1007
原创 Linux驱动学习day9(异常与中断处理)
1、(a)设置中断源,让其可以产生中断。(b)设置中断控制器(屏蔽/优先级)。(c)打开CPU总开关(使能中断)。2、执行程序3、产生中断:按下按键-->发送信号-->中断控制器-->cpu。4、CPU每执行完一段指令都会检查有无中断异常产生。5、发现有中断异常产生,开始处理,对于不同的异常跳去不同的地址执行程序。这些地址上只是一条跳转指令,跳去执行某个指令。(地址-->异常向量)6、处理中断异常(保存现场(各种寄存器)、处理异常中断、恢复现场)。
2025-06-27 22:38:52
707
原创 Linux驱动学习day8(按键驱动读取方式、GPIO、pinctrl子系统)
驱动只处理逻辑信号,硬件差异通过设备树隐藏起来,换板子只改设备树,不用动驱动,极大方便了维护和移植。这里要记住,我之前习惯将{ .compatible = "my,myled" }写成{ .compatible = "my , myled" },每个符号之后都有一个空格,并且将设备树中的compatible 也写成 "my , myled",但是这样写就会出现问题,加载驱动之后不会调用.probe函数,也就是说之后的都无法执行,只需要将空格去掉即可,一开始还以为逻辑出现了错误,一直找不到问题所在。
2025-06-26 22:14:56
493
原创 Linux驱动学习day7(使用设备树实现LED驱动(不含硬件操作))
今天重新复习了一下Linux中的面向对象/分离/分层思想,并且重新理解一下昨天学习的总线,platform_driver 和 platform_device。
2025-06-25 23:17:46
726
原创 Linux驱动学习day6(面向对象/分层/分离设计思想、设备树引入)
尝试匹配设备与驱动。匹配到的话执行probe函数,获取板子上的资源保存到static int g_ledpins[100]数组中,并且创建设备结点 , 为了防止相互依赖 , 在led_drv.c中将创建设备结点和销毁设备结点单独提取出来 , 并且使用EXPORT_SYMBOL(register_led_operations) , 这是为了在别的代码中也可以使用这个函数。2、分配/设置/注册platform_driver结构体,在probe函数里,分配/设置/注册file_operations结构体。
2025-06-23 22:33:36
952
原创 Linux驱动学习day5(配置静态路由)
最近有点忙,计划需要往后拖一拖,好好学习!今天主要遇到的问题是学校的网络需要通过网页方式认证账号密码,而RK3568开发板没有图形界面,无法完成此类认证,因此即使连接了学校的网线也无法联网。为了解决这个问题,并实现Ubuntu主机与开发板之间的文件共享与通信,我将Ubuntu的一张有线网卡与开发板直接连接,并将其配置在同一网段。我的理解是:这样设置后,Ubuntu主机可以作为网关或桥接设备,使得开发板能够访问Ubuntu共享的文件夹并进行网络通信。
2025-06-18 22:06:04
273
原创 Linux驱动学习day4(通用的GPIO操作方法、操作硬件LED灯)
GPIO(通用的输入输出口)引脚操作方法GPIO(通用的输入输出口)引脚操作方法主要的步骤分为4步:1、使能某个GPIO模块 2、设置引脚模式是GPIO 3、设置引脚位输入还是输出 4、设置引脚数据。寄存器操作原则:不要影响其他位。
2025-06-13 22:13:08
1097
1
原创 Linux驱动学习day3(cdev_init注册方式、应用程序和驱动交互方式)
在注册驱动的时候直接使用register_chrdev()的时候,不用指定主设备号,也可以不指定次设备号,这样会霸占一个主设备号下所有的次设备号,为了解决这个问题,使用alloc_chrdev_region(),该函数可以获得主设备号和可以指定次设备号的个数,并且使用cdev_init()和cdev_add()函数和重要的file_operations结构体挂钩。在入口函数和出口函数指定。
2025-06-08 22:55:14
1217
原创 Linux驱动学习day1(最简单驱动框架不含硬件操作)
阅读驱动源码的工具好难调(一开始时间都比较多花费在配置环境等上面),用vscode+clangd确实是很方便(配置好环境)。驱动学习加油!
2025-06-06 16:08:49
540
原创 嵌入式Linux之RK3568
进入瑞芯微发开工具RKDevTool,选择升级固件,上传到固件,记住这里要进入maskrom模式或者是loader模式,进入该模式之后点击升级即可。
2025-06-04 20:56:43
544
原创 嵌入式项目之mini2440系统制作烧写
在嵌入式开发中,**系统移植(Linux 系统定制)** 是常见的需求,主要原因在于:1. **官方镜像体积过大**:标准 Linux 发行版(如 Ubuntu)可能占用数 GB 存储,而嵌入式设备的 **Flash 存储容量有限**(如 256MB),因此需要裁剪和优化。2. **资源适配**:不同硬件(如 ARM 开发板)需要匹配专用的驱动和配置,直接使用通用镜像可能导致兼容性问题。
2025-06-01 16:36:50
896
原创 Linux网络编程day9 libevent库
开源。精简。跨平台(Windows,Linux,maxos)。专注于网络通信。源码包安装:参考README1、./configure 检查安装环境 生成makefile2、make 生成.o和执行文件3、sudo make install 将必要的资源拷贝至系统指定目录4、进入sample目录进行验证,运行demo验证库安装使用情况5、编译使用库的.c时,需要加 -levent。
2025-05-11 11:59:05
1402
原创 Linux网络编程day8本地套接字
本地套接字通过C/S模型实现进程间通信,与网络编程中的TCP C/S模型有所不同。在本地套接字中,socket函数的domain参数需设置为AF_UNIX,地址结构使用sockaddr_un,并通过bind函数绑定到本地文件路径。服务器端在bind前需调用unlink确保文件路径可用,客户端则需显式绑定并初始化服务器地址结构。通信过程中,服务器通过accept接收连接,客户端通过connect建立连接。本地套接字适用于同一主机上的进程间通信,避免了网络通信的复杂性。
2025-05-09 11:38:17
538
原创 Linux网络编程day7 线程池and UDP
满足销毁条件wait_exit_thr_num赋值,signal给阻塞在条件变量上的线程发送假条件满足信号,跳转至wait阻塞,阻塞线程会被假信号唤醒,使用pthread_exit。根据既定算法,使用上述3变量判断是否应该创建、销毁线程池中的指定步长的线程。满足创建条件pthread_create()回调任务线程函数。加锁--》lock--》整个结构体的锁。加锁--》lock--》整个结构体的锁。唤醒阻塞在条件变量上的线程。对于不稳定的网络层,采取完全不弥补的通信方式,默认还原网络状况。
2025-05-08 22:54:58
1429
原创 Linux 网络编程 day5 多路IO转接之改进select and poll
三种多路IO转接方法:select , poll , epoll改进select多路IO转接,使用数组来保存含有需要连接的套接字cfd,不用循环至1024,节约时间提高效率。
2025-05-06 22:00:49
972
原创 Linux网络编程 day4
2、主动关闭请求端ESTABLISHED-->发送FIN-->FIN_WAIT_1-->接收ACK-->FIN_WAIT_2(半关闭)-->接收对端FIN-->FIN_WAIT_2-->发送ACK-->TIME_WAIT-->等待2MSL时长-->CLOSE.4、被动关闭连接请求端ESTABLISHED-->接收SYN-->ESTABLISHED-->发送ACK-->CLOSE_WAIT-->发送FIN-->LAST_ACK-->接收ACK-->CLOSE.将待监听的文件描述符,添加到监听集合中。
2025-05-05 21:58:29
1349
原创 Linux网络编程 day3 五一结假
主动发起连接请求端,发送SYN标志位,请求建立连接。携带数据包包号、数据字节数(0)、滑动窗口大小。被动接收连接请求端,发送ACK标志位,同时携带SYN请求标志位。携带序号、确认序号、数据包包号、数据字节数(0)、滑动窗口大小。主动发起连接请求端,发送ACK标志位,应答服务器连接请求。携带确认序号、数据包包号。
2025-05-04 23:05:42
398
原创 Linux网络编程day2 (网络编程的函数好多好难记)
复习昨天学的socket编程,服务器端编程。服务器初始化serv_addr.sin_addr.s_addr的时候可以使用htonl(INADDR_ANY)。
2025-04-29 22:13:36
155
原创 Linux网络编程 day1(总算进入网络了)
自己重新手敲一遍使用条件变量实现生产者消费者模型。第一次写,一直在循环生产者,找了一下原因,发现当释放生产者的时候,忘记唤醒一下消费者了(没使用pthread_cond_signal())。思路还是正确的。
2025-04-28 17:42:16
1096
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人