- 博客(41)
- 收藏
- 关注
原创 正点原子RK3568学习日志20- 点亮一个led灯,字符设备驱动基础篇完结
先把呼吸灯临时关了,设备树那改了才能全关框架选择字符框架查看手册GPIO0_C0引脚GPIO PMU基地址PMU_GRF_GPIO0C_IOMUX_L 寄存器 复用关系寄存器寄存器地址为:PMU_GRF_GPIO0C_DS_0 寄存器 引脚驱动能力寄存器GPIO_SWPORT_DDR_H 寄存器 方向寄存器GPIO_SWAPORT_DR_H 寄存器 数据寄存器4。
2025-10-24 00:41:18
1122
原创 正点原子RK3568学习日志19- Linux错误处理 字符驱动框架完全体
内核错误码保存在errno-base.h文件使用goto语句处理的时候,应该遵循“先进后出”的原则用了class_create()和device_create()函数,必须使用IS_ERR()函数判断返回的指针是否是有效的,如果是无效的,需要调用PTR_ERR()函数将无效指针转换为错误码,并进行错误码的返回对于任何一个指针来说,必然存在三种情况,一种是合法指针,一种是NULL(也就是空指针),一种是错误指针(也就是无效指针)
2025-10-23 19:24:07
336
原创 正点原子RK3568学习日志18-一个驱动兼容不同设备
通过结构体变量中某个成员的首地址获取到整个结构体变量的首地址。 ptr是结构体变量中某个成员的地址。 type是结构体的类型 member是该结构体变量的具体名字container_of宏的作用是通过结构体内某个成员变量的地址和该变量名,以及结构体类型。找到该结构体变量的地址。
2025-10-23 18:45:51
466
原创 正点原子RK3568学习日志17-文件私有数据
将生成字符设备的一些硬件属性(设备号、类、设备名称等)全都写成了变量,通常在驱动开发中会为设备定义相关的设备结构体文件私有数据就是将私有数据private_data指向设备结构体。通过它可以将私有数据一路从open函数带到read, write函数层层传入。一般是在open 的时候赋值,read、write时使用struct file 结构体中专门为用户留了一个域用于定义私有数据。
2025-10-23 16:13:59
665
原创 正点原子RK3568学习日志16-内核空间与用户空间数据交互
kernel/include/linux/uaccess.h文件——copy_from_user和copy_to_userfile_operations结构体的进行了填充,该结构体的每一个成员都对应着一个系统调用,例如read、write等,在对应的实验中,只是对调用函数进行了标志打印对内核空间与用户空间的数据交换功能进行实现,实现设备的读写功能内核空间中的代码控制了硬件资源,用户空间中的代码只能通过内核暴露的系统调用接口来使用系统中的硬件资源。
2025-10-23 01:11:29
414
原创 正点原子RK3568学习日志15-杂项设备驱动
杂项设备的主设备号固定为10,内核源码/include/linux/miscdevice.h”文件——miscdevice结构体内核源码/include/linux/miscdevice.h”——misc_register函数,misc_deregister函数miscdevice结构体minor指次设备号 通常情况下将该参数设置为MISC_DYNAMIC_MINOR,表示自动分配子设备号name表示misc设备的名字,misc设备驱动注册成功之后,会在dev目录下生成名为name的设备节点。
2025-10-22 23:32:21
404
原创 正点原子RK3568学习日志14-字符设备驱动框架
驱动编译成驱动模块ko 运行驱动编译成模块insmod1.驱动向Linux内核进行设备号申请2.字符设备注册时,会对申请的设备号进行使用3.设备节节点来充当内核和用户层通信的桥梁4.操作设备文件 测试程序appstruct file_operations结构体就是把系统调用和驱动程序关联起来的关键数据结构。该结构体的每一个成员都对应着一个系统调用,读取file_operation中相应的函数指针,接着把控制权转交给函数,从而完成了Linux设备驱动程序的工作。
2025-10-21 00:25:39
1109
原创 正点原子RK3568学习日志13-创建设备节点
驱动编译成驱动模块ko 运行驱动编译成模块insmod前面成功的申请了设备号并且注册了相应的字符设备系统通过设备号对设备进行查找,而字符设备注册到内核并不能直接进行设备文件操作命令(打开、关闭、读、写等)需要相应的设备文件作为桥梁以此来进行设备的访问——设备节点设备节点被创建在/dev目录下,将内核中注册的设备与用户层进行链接,应用程序才能对设备进行访问/sys/class/ 目录——class_create(…)函数对class进行创建。
2025-10-20 23:09:26
1158
原创 正点原子RK3568学习日志12-注册字符设备
驱动编译成驱动模块ko 运行驱动编译成模块insmod“内核源码/include/linux/cdev.h”文件——struct cdev 结构体dev 记录了字符设备号、内核对象、文件操作file_operations结构体(设备的打开、读写、关闭等操作接口)等信息“内核源码/include/linux/cdev.h”文件,“内核源码/include/fs/char_dev.c”文件——设备初始化所用到的函数为cdev_init(),
2025-10-20 21:49:07
483
原创 正点原子RK3568学习日志11-申请字符设备号
驱动编译成驱动模块ko 运行驱动编译成模块insmod字符设备是指在I/O传输过程中以字符为单位进行传输的设备,可以使用与普通文件相同的文件操作命令(打开、关闭、读、写等)对字符设备进行操作,是Linux驱动中最基本的一类设备驱动,例如最常见的LED、按键、IIC、SPI,LCD等都属于字符设备的范畴。要想对字符设备进行操作,需要通过设备号来对相应的设备进行查找主设备号用来表示一个特定的驱动,次设备号用来管理下面的设备/include/linux/fs.h”文件。
2025-10-20 21:12:54
535
原创 Linux驱动第一期1-10-驱动基础总结
1.在使用module_init(hello_world)时,hello_world()函数指针会被放置在.initcall6.init段处。2.内核启动时,会执行do_initcall()函数,该函数根据指针数组initcall_levels[6]找到_initcall6_start,3.在include/asm-generic/vmlinux.lds.h文件中可以查到_initcall6_start对应.initcall6.init段的起始地址。4.然后,依次取出该段中的函数指针,并执行这些函数。
2025-10-19 22:43:33
1441
原创 正点原子RK3568学习日志10-向系统条件一个系统调用
在实验:将驱动编译进内核的基础上,绝对路径使用交叉编译器1.编译驱动进内核字符驱动目录kernel/drives/char/2.新建目录,03_helloworld, 包含helloworld.c Makefile Kconfig3.helloworld.c写你自己的程序4.Kconfig config后面那个名字是自己定义的,决定了你Makefile里的名字三个状态: *驱动编译进内核 M驱动编译成模块 无就是什么都不干。
2025-10-19 18:14:50
884
原创 正点原子RK3568学习日志9-修改insmod命令内核如何运行ko文件
您这个程序的完整工作流程是:通过 main 函数的参数 argv[1],获取用户想要加载的模块文件名。使用 open() 函数打开这个 .ko 文件,得到一个代表它的“ID号”——文件描述符 fd。调用 syscall(),请求内核执行编号为 __NR_finit_module 的操作。将文件描述符 fd 作为参数传递给内核,让内核知道具体要加载哪个文件。内核收到请求后,会读取 fd 对应的文件内容,并尝试将其作为内核模块加载进内存。程序根据系统调用的返回值,判断加载是否成功,并最终退出。
2025-10-18 02:17:04
1037
原创 正点原子RK3568学习日志8-驱动代码使用Makefile的宏
说明:此次是为了宏,找不到定义的宏在哪,可以自己在自己的Makefile或者链接脚本里面定义。一些相关目录:需要到顶层makefile, 就是kernel下的KBUILD_CFLAGS_MODULE := -DMODULE 驱动编译成ko.文件 :=可以使用+=main.c01_define目录下a.c Makefilea.c 重点是那个DEBUG宏,需要在Makefile定义。
2025-10-17 22:33:17
1016
原创 正点原子RK3568学习日志7-编译进内核的驱动怎么运行
initcall0_start等以_start结尾的相关变量记录了.initcall0.init等段的首地址,这些变量在 init/main.c中通过extern关键字进行引用,并将这些首地址放置在数组initcall_levels中,具在使用module_init(hello_world)时,hello_world()函数指针会被放置在.initcall6.init段处。
2025-10-16 23:33:15
667
原创 正点原子RK3568学习日志5-将驱动编译到内核
编译:1.SDK整体编译,在SDK根目录下, ./.build.sh all 这个是build.h脚本,vim build.h可以进行查看,或者 ./build.sh -h编译完,进行打包到rockdev, ./build.sh firmware rockdev指向output/firmware目录再执行 ./build.sh updateimg 打包,会在output/firmware目录下生成update.img, 编译后的文件会进入bool.img文件。
2025-10-15 14:25:16
1726
原创 正点原子RK3568学习日志4-拷贝.ko文件到rk3568板子上
MaskRom模式: 上电,OTG接线,先按update键,再按reset适用于板子成砖模式Loader模式: 上电,OTG接线,先按音量+,再按reset适用于烧写镜像,升级固件cpu的引导程序:bootrom: cpu内部的存储空间,固化一段代码,引导程序的bootrom 开始spi nand flash -> nand flash -> emmc -> sdmmc -> 初始化usbddr 结尾启动操作系统: SDK包 用Linux的。
2025-10-14 16:27:27
1353
原创 正点原子RK3568学习日志3-编译第一个驱动程序helloworld
1.将驱动程序放入Linux内核里面,然后编译Linux内核,将驱动编译到Linux内核里面2.将驱动程序编译成内核模块,独立于Linux内核模块之外, .ko文件->内核模块。
2025-10-13 10:18:55
893
原创 鸟哥的Linux私房菜 第三部分: 学习shell与shell script
通过特定的元字符和语法规则,实现对字符串的高效搜索、替换、验证和提取普通字符(如a1)直接匹配自身元字符作用示例匹配任意单个字符(除换行符)a.c匹配行开始位置^Hello匹配行结束位置world$前一个字符出现 0 次或多次ab*c前一个字符出现 1 次或多次ab+c→ "abc", "abbc" (不匹配 "ac")?前一个字符出现 0 次或 1 次ab?c``转义字符\.匹配真正的点号(非元字符)[ ]字符集合。
2025-10-09 21:52:24
808
原创 鸟哥的Linux私房菜:第二部分Linux文件目录与磁盘格式总结1
文件拥有者users: 对文件拥有完全控制权,可修改权限及归属组用户组group: 组成员共享文件权限,适用于团队协作其他人others: 非所有者且非组成员,权限需要严格限制5.2.1 Linux文件属性文件类型权限 链接数 文件拥有者 文件所属组 文件大小 文件最后修改时间 文件名第一栏代表文件的类型与权限,第一个字符代表这个文件是目录,文件或链接文件。
2025-10-06 17:28:51
1333
原创 鸟哥的Linux私房菜第一部分:Linux的规则与安装日志
1.电脑:输入单元,输出单元,CPU内部的控制单元,算术逻辑单元与内存2.CPU架构:RISC(ARM架构)和CISC3.操作系统也是一组程序,这组程序的重点在于管理电脑的所有活动以及驱动系统中所有的硬件操作系统内核Kernel:包含系统调用接口,进程管理,内存管理,文件系统管理,设备驱动系统调用System Call。就是API 应用程序编程接口。
2025-10-03 02:28:37
636
原创 C语言中的链表详细解释
1.约瑟夫问题(Josephus Problem)是单向循环链表的经典应用。动态内存分配区(malloc/new)自动管理(编译器控制),手动释放前有效。手动管理(程序员控制),调用结束销毁。LIFO(后进先出)结构。:存储下一个节点的地址。未初始化全局/静态变量。4.在指定位置插入节点。5.在指定位置插入节点。初始化全局/静态变量。程序启动时初始化为0。
2025-10-02 00:12:57
918
原创 CPrimer Plus第五章 运算符,表达式和语句总结1
关系运算符用于比较操作数,结果为真(1)或假(0运算符含义示例说明小于a < b<=小于或等于a <= b大于a > b>=大于或等于a >= b==等于a == b,误用可能导致逻辑错误或无限循环。!不等于a!= b:在C语言中,所有,。
2025-10-01 16:44:09
421
原创 CPrimer Plus第十六章C预处理器和C库总结2-qsort函数
这个函数决定了排序的顺序(升序、降序、按特定规则)int (*compar)(const void *, const void *)这是一个。后面(符合降序:小数在后)。是为了保证函数不会修改原始数据,并且。可以处理任何数据类型的数组。参数(指向要比较的两个元素的指针)前面(符合降序:大数在前)。数组(字符串数组)按字典序升序排序。是指向数组中两个待比较元素的指针。 要降序,只需反转比较结果。 对任意类型的数组进行排序。的值大),结果是负数,表示。的值小),结果是正数,表示。
2025-10-01 02:47:21
774
原创 CPrimer Plus第八章 字符输入/输出和输入验证总结1
1.可以把它想象成一个临时的“等候区”,用户输入的字符不会立即被程序处理,而是先存放在这里2.:将多个字符作为一块数据传输,比逐个发送节省时间:在按下回车键前,可以修正输入错误3.:遇到换行符(即按下回车键)时刷新缓冲区。:只有当缓冲区被填满时才刷新。常见于:输入立即被程序使用,无需等待。某些交互式场景(如游戏)可能需要。
2025-09-30 03:00:12
850
原创 CPrimer Plus第十六章C预处理器和C库总结1
2.预处理器直接替换文本,不进行计算(如调用会展开为而非25)3.重定义规则:仅当新旧定义时才允许重定义(如与允许,但与会报错)
2025-09-29 22:40:00
293
原创 正点原子RK3568学习日志1-环境的安装
支持创建SSH、Telnet、Rsh、Xdmc、RDP、VNC、FTP、SFTP、串口(Serial COM)等超多远程连接功能。开发板光盘 A 盘-基础资料→04、软件→FileZilla_3.61.0_win64-setup.exe。文档:【正点原子】Ubuntu环境搭建&VSCode安装使用V1.0。FileZilla使用方法:文件-站点管理器-新站点-就连接成功了,可以互相传文件了。注意:记得放在盘的第一层文件夹,不过多介绍了,这个太基础了。确保这两行长这样就行。
2025-09-24 03:21:33
1553
原创 CPrimer Plus第九章 函数总结1
returnvoid2.实参(Actual Argument)函数调用时传入的具体值,主调函数中的常量、变量或表达式,值被复制到栈中供被调函数读取。
2025-09-22 01:46:17
1061
原创 CPrimer Plus第十四章 结构和其他数据形式总结1
typedef 是一个关键字,用于为已有的数据类型创建别名(Alias)typedef 原类型 新类型名;//为现有类型定义一个新名称(非创建新类型)// Length 是 int 的别名// 等价于 int len = 10;// 等价于 char* const s1(指针不可变)// 指向的数据不可变// 等价于 int* p1, p2;→ p2是int而非指针!// p3和p4都是指针应用场景:简化复杂类型声明// 未使用 typedef// 函数指针声明复杂。
2025-09-22 00:37:14
1499
原创 CPrimer Plus第十章数组和指针总结1
本文介绍了C语言中数组和指针的核心概念及操作。主要内容包括:1)一维数组的定义和使用,演示了通过索引和sizeof计算数组元素个数;2)二维数组的声明与遍历,展示了年降水量统计的实用案例;3)指针与数组的关系,重点讲解了数组名即首元素地址的特性,以及指针运算的8种操作;4)const修饰符在指针中的不同用法,包括指向常量的指针、指针常量和指向常量的指针常量;5)指针与多维数组的结合使用,通过zippo示例解析了双重间接寻址的机制,并介绍了变长数组(VLA)的应用。这些内容涵盖了数组和指针的基础操作到高级应用
2025-09-15 01:07:38
185
原创 C语言中的复合字面量的详细解释1
允许在表达式中直接创建匿名的, 具有特定类型(结构体,联合体或数组)的对象,并同时对其初始化,简单来说,就是能在你需要某个类型值的地方,直接构造一个该类型的值,无需先定义一个变量。
2025-09-12 19:17:49
329
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅