RK3568驱动指南|第五期-中断-第44章 共享工作队列实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。


【公众号】迅为电子

【粉丝群】824412014(加群获取驱动文档+例程)

【视频观看】嵌入式学习之Linux驱动(第五期_中断_全新升级)_基于RK3568

【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板


第44章 共享工作队列实验

在上个章节我们学习了中断下文的一种实验方式——软中断,本章节我们来学习中断下文的另一种实现方式——工作队列。工作队列是操作系统中管理和调度异步任务执行的一种机制,接下来开始学习工作队列吧。

44.1 什么是工作队列

工作队列是实现中断下半部分的机制之一,是一种用于管理任务的数据结构或机制。它通常用于多线程,多进程或分布式系统中,用于协调和分配待处理的任务可用的工作线程或工作进程

工作队列的基本原理是将需要执行的任务按顺序排列在队列中,并提供一组工作线程或者工作进程来处理队列中的任务。当有新的任务到达时,它们会被添加到队列的末尾,工作线程或工作进程从队列的头部获取任务,并执行相应的处理操作。

工作队列和之前学习的tasklet有什么不同呢?tasklet也是实现中断下半部分的机制之一。他们最主要的区别是tasklet不能休眠,而工作队列是可以休眠的,所以tasklet可以用来处理比较耗时间的事情,而工作队列可以处理更耗时间的事情。

工作队列将工作推后以后,会交给内核线程去执行。Linux在启动过程中会创建一个工作者内核线程,这个线程创建以后处于sleep状态。当有工作需要处理的时候,会唤醒这个线程去处理工作。

在内核中,工作队列包括共享工作队列和自定义工作队列这俩种类型。这两种类型的工作队列具有不同的特点和用途。

1  共享队列是由内核管理的全局工作队列,用于处理内核中一些系统级任务。共享工作队列是内核中一个默认工作队列,可以由多个内核组件和驱动程序共享使用。

2 自定义工作队列是由内核或驱动程序创建的特定工作队列,用于处理特定的任务。自定义工作队列通常与特定的内核模块或驱动程序相关联,用于执行该模块或驱动程序相关的任务。

 本章节我们先来学习共享工作队列相关的知识。

在Linux 内核中,使用 work_struct 结构体表示一个工作项,这些工作组织成工作队列,工作队列使用 workqueue_struct 结构体表示,如下图所示,流水线相当于工作队列,流水线上一个个等待处理的物料相当于一个个工作。机器相当于内核线程或进程。

图 44-1

work_struct 结构体表示一个工作项,定义在include/linux/workqueue.h中,如下所示:

struct work_struct {atomic_long_t data; struct list_head entry;work_func_t func; /* 工作队列处理函数 */
};
typedef void (*work_func_t)(struct work_struct *work);  //工作函数

44.2 工作队列相关接口函数

44.2.1 初始化函数

在实际的驱动开发中,我们只需要定义工作项(work_struct)即可,关于工作队列和工作者线程我们基本不用去管。简单创建工作很简单,直接定义一个 work_struct 结构体变量即可,然后使用 INIT_WORK 宏来初始化工作,INIT_WORK 宏定义如下:

#define INIT_WORK(_work,_func)

INIT_WORK 宏接受两个参数:_work 和 _func,分别表示要初始化的工作项和工作项的处理函数。

也可以使用 DECLARE_WORK 宏一次性完成工作的创建和初始化,宏定义如下:

#define DECLARE_WORK(n, f)

参数n 表示定义的工作(work_struct),f 表示工作对应的处理函数。

44.2.2 调度/取消调度工作队列函数

和 tasklet 一样,工作也是需要调度才能运行的,工作的调度函数为 schedule_work,函数原型如下所示:

static inline bool schedule_work(struct work_struct *work)

参数是指向工作项的指针。这个函数作用是将工作项提交到工作队列中,并请求调度器在合适的时机执行工作项。该函数会返回一个布尔值,表示工作项是否成功被提交到工作队列。

如果想要取消该工作项的调度,使用以下函数:

bool cancel_work_sync(struct work_struct *work);

参数是指向工作项的指针。这个函数的作用是取消该工作项的调度。如果工作项已经在工作队列中,它将被从队列中移除。如果工作项已经在工作队列中,它将被从队列中移除,并等待工作项执行完成。函数返回一个布尔值,表示工作项是否成功取消。

44.3 实验程序的编写

44.3.1 驱动程序编写

本实验对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\34_workqueue\module

本实验将实现注册显示屏触摸中断,每按当触摸LCD显示屏就会触发中断服务函数,在中断服务函数中提交工作项到共享工作队列中,打印“This id test_interrupt”和“This is test_work”。

在驱动程序中的模块初始化函数中,我们将GPIO转换为中断号,并使用request_irq函数请求中断,然后初始化工作项。当中断被触发时,中断处理函数被调用,并将工作项提交到共享工作队列中,最终由工作项处理函数异步执行。编写完成的interrupt.c代码如下所示,添加的代码已加粗表示。

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
int irq;
struct work_struct test_workqueue;
// 工作项处理函数
void test_work(struct work_struct *work)
{msleep(1000);printk("This is test_work\n");
}
// 中断处理函数
irqreturn_t test_interrupt(int irq, void *args)
{printk("This is test_interrupt\n");// 提交工作项到工作队列schedule_work(&test_workqueue);return IRQ_RETVAL(IRQ_HANDLED);
}static int interrupt_irq_init(void)
{int ret;irq = gpio_to_irq(101); // 将GPIO映射为中断号printk("irq is %d\n", irq);// 请求中断ret = request_irq(irq, test_interrupt, IRQF_TRIGGER_RISING, "test", NULL);if (ret < 0){printk("request_irq is error\n");return -1;}// 初始化工作项INIT_WORK(&test_workqueue, test_work);return 0;
}static void interrupt_irq_exit(void)
{free_irq(irq, NULL); // 释放中断printk("bye bye\n");
}
module_init(interrupt_irq_init);
module_exit(interrupt_irq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("topeet");

44.4 运行测试

44.4.1 编译驱动程序

在上一小节中的interrupt.c代码同一目录下创建 Makefile 文件,Makefile 文件内容如下所示:

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m += interrupt.o    #此处要和你的驱动源文件同名
KDIR :=/home/topeet/Linux/linux_sdk/kernel    #这里是你的内核目录                                                                                                                            
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modules    #make操作
clean:make -C $(KDIR) M=$(PWD) clean    #make clean操作

对于Makefile的内容注释已在上图添加,保存退出之后,来到存放interrupt.c和Makefile文件目录下,如下图(图44-2)所示:

图 44-2

然后使用命令“make”进行驱动的编译,编译完成如下图(图44-3)所示:

图 44-3

编译完生成interrupt.ko目标文件,如下图(图44-4)所示:

图 44-4

至此驱动模块就编译成功了,接下来进行测试。

44.4.2 运行测试

开发板启动之后,使用以下命令进行驱动模块的加载,如下图(图44-5)所示:

insmod interrupt.ko

图44-5

加载驱动之后,可以看到申请的中断号被打印了出来,然后用手触摸连接的LVDS 7寸屏幕,打印如下图(44-6)所示:

在上图中,可以看到打印中断处理函数中添加的打印“This is test_interrupt”被多次打印,说明触发了好几次中断上文,那么中断上文会多次调度中断下文,所以也会打印工作项处理函数中添加的打印“This is test_work”。但是为什么只会打印俩次“This is test_work”呢?这是因为在中断上文调度工作项处理函数之后,内核没有来得及去执行工作项处理函数,没有执行相当于无效操作,有效的执行则打印了俩次“This is test_work”。

最后可以使用以下命令进行驱动的卸载,如下图(图44-7)所示:

rmmod interrupt

 

图 44-7

至此,共享工作队列实验就完成了。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/141894.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Excel 语法

目录 语法 逐步创建公式 对单元格使用公式 另一个例子 语法 Excel中的一个公式用于进行数学计算。公式总是以单元格中键入的等号开头&#xff0c;然后是您的计算。 注意&#xff1a;您可以通过选择单元格并键入等号&#xff08;&#xff09;来声明该单元格 逐步创建公式…

【Java 基础篇】Java 模块化详解

Java 9引入了一项重要的功能&#xff1a;模块化&#xff08;Module System&#xff09;。模块化是一种将代码和资源封装到可重用和独立的单元中的方法&#xff0c;它有助于改善代码的可维护性、可重用性和安全性。本文将介绍Java模块化的基本概念、如何创建和使用模块以及一些最…

基于微信小程序的美术馆预约平台设计与实现(源码+lw+部署文档+讲解等)

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…

SLAM从入门到精通(IMU参数的读取)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 上一篇文章我们说过&#xff0c;对于差速轮来说&#xff0c;旋转的计算很多程度上依赖于thetatan(theta)这个公式来进行的。但是&#xff0c;我们也…

以太坊代币标准ERC20、ERC165、ERC721

两个概念 ERC(Ethereum Request for Comment) 以太坊意见征集稿EIP(Ethereum Improvement Proposals)以太坊改进提案 ERC和EIP用于使得以太坊更加完善&#xff1b;在ERC中提出了很多标准&#xff0c;用的最多的标准就是它的Token标准; 有哪些标准详细见https://eips.ethereum…

中国TO B投资,迈入第二周期

2023年,中国TOB正在愈发成熟,迈进第二个周期的趋势已经体现在融资金额上。 作者|斗斗 编辑|皮爷 出品|产业家 TOB&#xff0c;依旧是一级市场的大热门。 统计数据显示&#xff0c;截止2023年8月31日&#xff0c;TOB领域共发生融资事件406起&#xff0c;同比2022年减少…

phpstudy2016 RCE漏洞验证

文章目录 漏洞描述漏洞验证 漏洞描述 PHPStudyRCE&#xff08;Remote Code Execution&#xff09;&#xff0c;也称为phpstudy_backdoor漏洞&#xff0c;是指PHPStudy软件中存在的一个远程代码执行漏洞。 漏洞验证 打开phpstudy2016&#xff0c;用bp自带的浏览器访问www目录下…

Vue3+element-plus切换标签页时数据保留问题

记录一次切换标签页缓存失效问题&#xff0c;注册路由时name不一致可能会导致缓存失效

Unity中Shader通道ColorMask

文章目录 [TOC](文章目录) 前言一、ColorMask是用来干什么的二、怎么做到和 Unity UI 中的 Shader 一样根据UI层级自动适配Shader中模板测试值1、借鉴Unity官方的 UI Shader 前言 Unity中Shader通道ColorMask 一、ColorMask是用来干什么的 ColorMask RGB | A | 0 | R、G、B、…

雨课堂 运动与健康 网课参考资料

整理于网络&#xff1a;仅用于学习交流讨论&#xff0c;侵删 参考文档&#xff1a;https://www.doc88.com/p-99629779008847.html 参考视频&#xff1a; 运动与健康&#xff08;2021年秋网课答案 69题版本&#xff09;_哔哩哔哩 | https://www.bilibili.com/video/av210112837/…

WebGL 用鼠标控制物体旋转

目录 鼠标控制物体旋转 如何实现物体旋转 示例程序&#xff08;RotateObject.js&#xff09; 代码详解 示例效果 鼠标控制物体旋转 有时候&#xff0c;WebGL程序需要让用户通过鼠标操作三维物体。这一节来分析示例程序RotateObject&#xff0c;该程序允许用户通过拖动&…

DT 卡通材质学习 一

渐变着色器 相交线 笔刷和卡通结合使用 修改器

计算机类软件方向适合参加的比赛

前言 博主是一名计算机专业的大三学生&#xff0c;在校时候参加了很多比赛和训练营&#xff0c;现在给大家博主参加过的几个的比赛&#xff0c;希望能给大一大二的学生提供一点建议。 正文 最近也有比赛的&#xff0c;我会从时间线上来给大家推荐一些比赛&#xff0c;并且给…

大屏大概是怎么个开发法(前端)

写在前面&#xff0c;博主是个在北京打拼的码农&#xff0c;从事前端工作5年了&#xff0c;做过十多个大大小小不同类型的项目&#xff0c;最近心血来潮在这儿写点东西&#xff0c;欢迎大家多多指教。 对于文章中出现的任何错误请大家批评指出&#xff0c;一定及时修改。有任何…

AutoDL云服务器的使用

目录 简介使用流程租借连接服务器输入登录指令以及密码设置服务器环境和同步文件 使用技巧查看远程主机资源上传下载数据如果上传的文件是压缩包 我的心得将大文件用百度云盘上传&#xff0c;小文件通过同步区域上传跨实例拷贝数据如果本实例没GPU选择其他实例 简介 使用此云服…

位移贴图的实现原理

在以前的文章中介绍过GLTF编辑器 &#xff0c; 编辑器可以对模型的各种材质纹理进行编辑修改&#xff0c;但是有一些新手用户可能对这些材质纹理不太了解&#xff0c;所以我收集了一些资料对这些材质纹理做一下详细的介绍&#xff0c;今天这篇文章主要是介绍位移贴图。 1、什么…

CMOS图像传感器——Stack Pixel(2)

在去年的时候, 就写过Sony大法的Stack Pixel CMOS图像传感器——Stack Pixel_stacked-pixel cis_沧海一升的博客-CSDN博客对索尼的2-Layer Transistor Pixel技术进行了介绍_stacked-pixel cishttps://blog.csdn.net/qq_21842097/article/details/127007460 IEDM 2021 上…

【好文推荐】openGauss 5.0.0 数据库安全——全密态探究

前言 写此文章的目的&#xff0c;主要是验证&#xff1a; openGauss 5.0.0 数据库能够实现哪种加密方式的全密态全密态数据库的特点 一、全密态介绍 全密态数据库意在解决数据全生命周期的隐私保护问题&#xff0c;使得系统无论在何种业务场景和环境下&#xff0c;数据在传…

Vue中的深度监听(Deep Watch):详细解析与实际示例

Vue中的深度监听&#xff08;Deep Watch&#xff09;&#xff1a;详细解析与实际示例 Vue.js 是一款流行的前端 JavaScript 框架&#xff0c;其响应式系统是其核心特性之一。通过响应式系统&#xff0c;Vue允许开发者轻松地监听数据的变化并对其做出响应。在某些情况下&#x…

Redis的softMinEvictableIdleTimeMillis和minEvictableIdleTimeMillis参数

背景&#xff1a; Redis的softMinEvictableIdleTimeMillis&#xff0c;minEvictableIdleTimeMillis是一个令人疑惑两个参数&#xff0c;特别是当它和minIdle组合起来时就更难理解了&#xff0c;本文就来梳理下他们的之间的关系 softMinEvictableIdleTimeMillis&#xff0c;mi…