RK3568 linux驱动开发笔记(迅为)
文章平均质量分 80
温人之周.
这个作者很懒,什么都没留下…
展开
-
linux中断下文工作队列之工作队列传参(中断七)
首先我们定义工作项结构,如下所示,在结构体 struct work_data 中定义了需要传递给工作项处理函数的参数 a 和 b,然后定义一个类型为 struct work_data 的变量test_workqueue_work。当中断触发时,在中断处理函数 test_interrupt 中,通过调用queue_work 函数将工作项test_workqueue_work.test_work 提交到工作队列 test_workqueue 中。然后在模块初始化函数中,为工作项的参数 a 和 b 赋值。原创 2023-10-31 20:25:13 · 387 阅读 · 0 评论 -
linux中断下文工作队列之延迟工作(中断六)
延迟工作是一种将工作的执行延迟到稍后时间点进行处理的技术。通常情况下,当某个任务需要花费较长时间,不需要立即执行或需要按时执行时,延迟工作就会派上用场。延迟工作的基本思想是将任务放入一个队列中,然后由后台的工作进程会任务调度程序来处理队列中的任务。任务可以在指定的延迟时间后执行,也可以根据优先级,任务类型或者其他条件进行排序和处理。延迟工作在许多应用场景中都非常有用,尤其是在需要处理大量任务,提供系统性能和可靠性的情况下。以下是一些常用的应用场景。原创 2023-10-31 20:14:12 · 551 阅读 · 0 评论 -
linux中断下文工作队列之自定义工作队列(中断五)
该函数参数是一个指向 struct workqueue_struct 类型的指针wq。原创 2023-10-31 19:57:57 · 299 阅读 · 0 评论 -
linux中断下文工作队列之共享工作队列(中断四)
工作队列是实现中断下半部分的机制之一,是一种用于管理任务的数据结构或机制。它通常用于多线程,多进程或分布式系统中,用于协调和分配待处理的任务给可用的工作线程或工作进程。工作队列的基本原理是将需要执行的任务按顺序排列在队列中,并提供一组工作线程或者工作进程来处理队列中的任务。当有新的任务到达时,它们会被添加到队列的末尾,工作线程或工作进程从队列的头部获取任务,并执行相应的处理操作。工作队列和之前学习的 tasklet 有什么不同呢?tasklet 也是实现中断下半部分的机制之一。原创 2023-10-26 20:15:33 · 194 阅读 · 0 评论 -
linux中断下文之软中断(中断三)
Linux 源码 linux_sdk/kernel/include/linux/interrupt.h 文件中定义了一个枚举类型,用于标识软中断的不同类型或优先级。每个枚举常量对应一个特定的软中断类型。enum {HI_SOFTIRQ:高优先级软中断TIMER_SOFTIRQ:定时器软中断NET_TX_SOFTIRQ:网络传输发送软中断NET_RX_SOFTIRQ:网络传输接收软中断BLOCK_SOFTIRQ:块设备软中断IRQ_POLL_SOFTIRQ:中断轮询软中断。原创 2023-10-26 19:53:14 · 143 阅读 · 0 评论 -
linux中断下文之tasklet(中断二)
在申请 GPIO 中断时使用 request_irq,但是request_irq绑定的中断服务程序指的是中断上文。在 Linux 内核中,tasklet 是一种特殊的软中断机制,被广泛用于处理中断下文相关的任务。它是一种常见且有效的方法,在多核处理系统上可以避免并发问题。Tasklet 绑定的函数在同一时间只能在一个 CPU 上运行,因此不会出现并发冲突。然而,需要注意的是,tasklet 绑定的函数中不能调用可能导致休眠的函数,否则可能引起内核异常。原创 2023-10-26 19:37:31 · 266 阅读 · 0 评论 -
linux中断(中断一)
中断是操作系统中至关重要的机制,它能够显著提高系统的响应性能和并发处理能力。中断是指在 CPU 正常运行期间,由外部或内部事件引起的一种机制。当中断发生时,CPU会停止当前正在执行的程序,并转而执行触发该中断的中断处理程序。处理完中断处理程序后,CPU 会返回到中断发生的地方,继续执行被中断的程序。中断机制允许CPU在实时响应外部或内部事件的同时,保持对其他任务的处理能力。原创 2023-10-26 19:06:19 · 228 阅读 · 0 评论 -
Linux驱动调试方法(高级字符设备八)
在编写Linux驱动程序时,通常都使用 printk 函数打印相应的提示信息从而对驱动进行调试,除了printk 函数之外,还有其他的方式来调试驱动呢。原创 2023-10-26 08:37:31 · 187 阅读 · 0 评论 -
Linux的ioctl 驱动传参(高级字符设备七)
ioctl 是设备驱动程序中用来控制设备的接口函数,一个字符设备驱动通常需要实现设备的打开、关闭、读取、写入等功能,而在一些需要细分的情况下,就需要扩展新的功能,通常以增设 ioctl()命令的方式来实现。原创 2023-10-25 20:31:42 · 384 阅读 · 0 评论 -
Linux 内核打印(高级字符设备六)
内核所有的打印信息都会输出到循环缓冲区 ‘log_buf’,为了能够方便的在用户空间读取内核打印信息,Linux 内核驱动将该循环缓冲区映射到了/proc 目录下的文件节点kmsg。通过cat 或者其他应用程序读取 Log Buffer 的时候可以不断的等待新的log,所以访问/proc/kmsg的方式适合长时间的读取 log,一旦有新的 log 就可以被打印出来。在终端使用 dmseg 命令可以获取内核打印信息,该命令的具体使用方法如下所示:dmesg 命令。-C,–clear 清除内核环形缓冲区。原创 2023-10-25 20:13:16 · 596 阅读 · 0 评论 -
Linux 内核定时器(高级字符设备五)
在 Linux 内核中很多函数是基于定时器进行驱动的,但是内核定时器的精度并不高,所以不能作为高精度定时器使用。并且内核定时器的运行没有周期性,到达计时终点后会自动关闭。如果要实现周期性定时,就要在定时处理函数中重新开启定时器。/**/#endifstructtimer_list0例如可以使用以下代码对定时器和相应的定时处理函数进行定义//定义一个定时器定时器定义完成之后还需要通过一系列的 API 函数来初始化此定时器,部分函数说明如下函数作用。原创 2023-10-25 20:04:19 · 283 阅读 · 0 评论 -
linux信号驱动IO(高级字符设备四)
信号驱动 IO 不需要应用程序查询设备的状态,一旦设备准备就绪,会触发SIGIO信号,进而调用注册的处理函数。原创 2023-10-25 19:39:25 · 216 阅读 · 0 评论 -
linux的IO 多路复用(高级字符设备三)
IO 多路复用是一种同步的 IO 模型。IO 多路复用可以实现一个进程监视多个文件描述符。一旦某个文件描述符准备就绪,就通知应用程序进行相应的读写操作。没有文件描述符就绪时就会阻塞应用程序,从而释放出 CPU 资源。在应用层 Linux 提供了三种实现 IO 多路复用的模型,分别是select、poll 和epoll。poll 函数和select 函数都可以监听多个文件描述符,通过轮询来获取已经准备好的文件描述符。但是epoll 函数将主动轮询变成了被动通知,当事件发生时被动接收通知。原创 2023-10-25 14:28:26 · 129 阅读 · 0 评论 -
Linux阻塞IO(高级字符设备二)
在 Linux 驱动程序中,阻塞进程可以使用等待队列来实现。等待队列是内核实现阻塞和唤醒的内核机制,以双循环链表为基础结构,由链表头和链表项两部分组成,分别表示等待队列头和等待队列元素//自旋锁struct list_head task_list //链表头。原创 2023-10-24 20:22:11 · 400 阅读 · 0 评论 -
linux驱动的IO 模型(高级字符设备一)
IO 是英文 Input 和 Output 的首字母,代表了输入和输出。操作系统(Linux)负责对计算机的资源进行管理和对进程进行调度,应用程序运行在操作系统上,处于用户空间。应用程序不能直接对硬件进行操作,只能通过操作系统提供的API 来操作硬件。需要将进程切换到内核空间,才能进行 IO 操作,并且应用程序不能直接操作内核空间的数据,需要把内核空间的数据拷贝到用户空间。应用程序运行在用户空间,它不存在实质的 IO 过程,真正的IO 是在操作系统执行的。原创 2023-10-24 19:35:30 · 116 阅读 · 0 评论 -
Linux 错误处理(字符设备基础三)
在Linux字符设备驱动中,即使是最简单的注册字符设备,也存在注册失败的可能性,因此在之前编写的驱动代码中采用检查函数返回值的方式,确认函数是否成功执行。原创 2023-10-24 19:20:19 · 194 阅读 · 0 评论 -
linux驱动文件私有数据(字符设备基础二)
文件私有数据的概念在 Linux 驱动中有着非常广泛的应用,文件私有数据就是将私有数据private_data 指向设备结构体。open 函数中私有数据的使用如下所示。Linux 中并没有明确规定要使用文件私有数据,但是在 linux 驱动源码中,广泛使用了文件私有数据,这是 Linux 驱动遵循的“潜规则”,实际上也体现了Linux 面向对象的思想。在上述代码中,定义了一个设备结构体 dev1,然后在 open 函数中,将私有数据private_data指向了设备结构体 dev1。原创 2023-10-24 19:01:32 · 340 阅读 · 0 评论 -
字符设备驱动框架(字符设备基础一)
编写字符设备驱动框架:首先驱动向 Linux 内核进行设备号申请,之后的字符设备注册时,会对申请的设备号进行使用。而 Linux 内核会将字符设备抽象成一个具体的struct cdev结构体,该结构体记录了字符设备的字符设备号、内核对象等信息,cdev_init(…)函数对结构体进行初始化之后,cdev_add(…)函数将设备号和 cdev 结构体进行链接,这时设备号才真正指向了内核中注册的设备。设备注册成功之后,此时还不能对字符设备进行文件操作,所以需要设备节节点来充当内核和用户层通信的桥梁。原创 2023-10-24 09:10:17 · 222 阅读 · 0 评论 -
RK3568驱动模块编译进内核
然后保存配置将信息保存到.config 文件。首先在drivers/char目录下创建hello文件夹,然后在hello文件夹下创建hello.c 文件、Kconfig和Makefile文件。编译成功之后,进入到 drivers/char/hello 目录下,可以看到会生成对应的.o 文件。需要修改上一级目录的 Kconfig 文件和 Makefile 文件,也就是 driver/char 目录。如果在图形化配置界面中选择的 M,也就是编译成驱动模块,则生成 helloworld.ko 文件。原创 2023-10-18 16:22:05 · 514 阅读 · 0 评论 -
Linux内核的.config 配置文件和defconfig 配置文件
图形化配置界面配置好了以后,会得到一个.config 配置文件。在编译内核的时候会根据这个.config 文件来编译内核。当我们使用 make menuconfig 的时候,会通过 mconf 程序去解析 Kconfig 文件,然后生成对应的配置文件.config。mconf 程序源码在内核源码 scripts/kconfig 目录下。有了.config 配置文件以后,内核就可以根据这个配置文件来编译内核,比如控制某些驱动编译进内核,或者控制某些驱动不编译内核。原创 2023-10-18 14:38:12 · 6050 阅读 · 0 评论 -
linux内核模块符号导出
驱动程序编译生成的 ko 文件是相互独立的,即模块之间变量或者函数在正常情况下无法进行互相访问。而一些复杂的驱动模块需要分层进行设计,这时候就需要用到内核模块符号导出。内核符号导出指的是在内核模块中导出相应的函数和变量,在加载模块时被记录在公共内核符号表中,以供其他模块调用。符号导出所使用的宏为 EXPORT_SYMBOL(sym)和 EXPORT_SYMBOL_GPL(sym)。它们定义在 “/include/linux/export.h”文件中。原创 2023-10-18 14:14:03 · 407 阅读 · 0 评论 -
linux驱动模块传参
驱动模块传参是一种可以随时向内核模块传递、修改参数的方法。例如可以传递串口驱动的波特率、数据位数、校验位、停止位等参数,进行功能的设置,以此节省编译模块的时间,大大提高调试速度Linux 内核提供了 module_param(name, type, perm)、module_param_array(name, type, nump, perm)宏和 module_param_string(name, string, len, perm)宏,分别进行基本类型、数组和字符串参数的传递。原创 2023-10-18 11:21:51 · 236 阅读 · 0 评论