Linux学习第25天:Linux 阻塞和非阻塞 IO 实验(二): 挂起

Linux版本号4.1.15   芯片I.MX6ULL                                    大叔学Linux    品人间百味  思文短情长 


        为方便和上一节的衔接,在正式开始学习前,先把本节的思维导图引入:

二、阻塞IO实验

1.硬件原理图分析

2.实验程序

#define IMX6UIRQ_NAME "blockio" /* 名字 */
//修改设备文件名字为“blockio”,当驱动程序加载成功以后就会在根文件系统中出现一个名为“/dev/blockio”的文件。
wait_queue_head_t r_wait; /* 读等待队列头 */
//在设备结构体中添加一个等待队列头 r_wait,因为在 Linux 驱动中处理阻塞 IO需要用到等待队列。
/* 唤醒进程 */
if(atomic_read(&dev->releasekey)) { /* 完成一次按键过程 *//* wake_up(&dev->r_wait); */wake_up_interruptible(&dev->r_wait);}
//定时器中断处理函数执行,表示有按键按下,先在 107 行判断一下是否是一次有效的按键,如果是的话就通过 wake_up 或者 wake_up_interruptible 函数来唤醒等待队列r_wait。
/* 初始化等待队列头 */
init_waitqueue_head(&imx6uirq.r_wait);
//采用等待事件来处理 read 的阻塞访问, wait_event_interruptible 函数等待
//releasekey 有效,也就是有按键按下。如果按键没有按下的话进程就会进入休眠状态,因为采用
//了 wait_event_interruptible 函数,因此进入休眠态的进程可以被信号打断。200 #if 0
201 /* 加入等待队列,等待被唤醒,也就是有按键按下 */
202 ret = wait_event_interruptible(dev->r_wait,
atomic_read(&dev->releasekey));
203 if (ret) {
204 goto wait_error;
205 }
206 #endif
208 DECLARE_WAITQUEUE(wait, current); /* 定义一个等待队列 */
209 if(atomic_read(&dev->releasekey) == 0) { /* 没有按键按下 */
210 add_wait_queue(&dev->r_wait, &wait); /* 添加到等待队列头 */
211 __set_current_state(TASK_INTERRUPTIBLE);/* 设置任务状态 */
212 schedule(); /* 进行一次任务切换 */
213 if(signal_pending(current)) { /* 判断是否为信号引起的唤醒 */
214 ret = -ERESTARTSYS;
215 goto wait_error;
216 }
217 __set_current_state(TASK_RUNNING); /*设置为运行状态 */
218 remove_wait_queue(&dev->r_wait, &wait); /*将等待队列移除 */

        首先使用 DECLARE_WAITQUEUE 宏定义一个等待队列,如果没有按键按下的话就使用 add_wait_queue 函数将当前任务的等待队列添加到等待队列头 r_wait 中。随后调用__set_current_state 函数设置当前进程的状态为 TASK_INTERRUPTIBLE,也就是可以被信
号打断。接下来调用 schedule 函数进行一次任务切换,当前进程就会进入到休眠态。如果有按
键按下,那么进入休眠态的进程就会唤醒,然后接着从休眠点开始运行。在这里也就是从第 213
行开始运行,首先通过 signal_pending 函数判断一下进程是不是由信号唤醒的,如果是由信号
唤醒的话就直接返回-ERESTARTSYS 这个错误码。如果不是由信号唤醒的(也就是被按键唤醒
的)那么就在 217 行调用__set_current_state 函数将任务状态设置为 TASK_RUNNING,然后在
218 行调用 remove_wait_queue 函数将进程从等待队列中删除。

3.运行测试

1)、编译驱动程序和测试APP

①、编译驱动程序
1 KERNELDIR := /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imxrel_imx_4.1.15_2.1.0_ga_alientek
......
4 obj-m := blockio.o//修改变量的值
......
11 clean:
12 $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

make -j32
编译成功以后就会生成一个名为“blockio.ko”的驱动模块文件。


②、编译测试APP
arm-linux-gnueabihf-gcc blockioApp.c -o blockioApp

2)、运行测试

depmod //第一次加载驱动的时候需要运行此命令
modprobe blockio.ko //加载驱动

驱动加载成功以后使用如下命令打开 blockioApp 这个测试 APP,并且以后台模式运行:
 

./blockioApp /dev/blockio &

        当按下 KEY0 按键以后 blockioApp 这个测试 APP 就会打印出按键值。输入“top”命令,查看 blockioAPP 这个应用 APP 的 CPU 使用率。

        使用“kill -9 PID”即可“杀死”指定 PID 的进程,例如杀死149进程命令为:kill -9 149

三、非阻塞IO实验

1.硬件原理图分析

2.实验程序

1)、驱动程序编写

#define IMX6UIRQ_NAME "noblockio" /* 名字 */
//修改设备文件名字为“noblockio”,当驱动程序加载成功以后就会在根文件系统
//中出现一个名为“/dev/noblockio”的文件。
 if (filp->f_flags & O_NONBLOCK) { /* 非阻塞访问 */if(atomic_read(&dev->releasekey) == 0) /* 没有按键按下 */return -EAGAIN;

        判断是否为非阻塞式读取访问,如果是的话就判断按键是否有效,也就是判断一下有没有按键按下,如果没有的话就返回-EAGAIN。

235 /*
236 * @description : poll 函数,用于处理非阻塞访问
237 * @param - filp : 要打开的设备文件(文件描述符)
238 * @param - wait : 等待列表(poll_table)
239 * @return : 设备或者资源状态,
240 */
241 unsigned int imx6uirq_poll(struct file *filp,
struct poll_table_struct *wait)
242 {
243 unsigned int mask = 0;
244 struct imx6uirq_dev *dev = (struct imx6uirq_dev *)
filp->private_data;
245
246 poll_wait(filp, &dev->r_wait, wait);
247
248 if(atomic_read(&dev->releasekey)) { /* 按键按下 */
249 mask = POLLIN | POLLRDNORM; /* 返回 PLLIN */
250 }
251 return mask;
252 }

        imx6uirq_poll 函数就是 file_operations 驱动操作集中的 poll 函数,当应用程序调用 select 或者 poll 函数的时候 imx6uirq_poll 函数就会执行。第 246 行调用 poll_wait 函数将等待队列头添加到 poll_table 中,第 248~250 行判断按键是否有效,如果按键有效的话就向应用程序返回 POLLIN 这个事件,表示有数据可以读取。

.poll = imx6uirq_poll,//设置 file_operations 的 poll 成员变量为 imx6uirq_poll。

2)、测试APP编写

52 #if 0
53 /* 构造结构体 */
54 fds.fd = fd;
55 fds.events = POLLIN;
56
57 while (1) {
58 ret = poll(&fds, 1, 500);
59 if (ret) { /* 数据有效 */
60 ret = read(fd, &data, sizeof(data));
61 if(ret < 0) {
62 /* 读取错误 */
63 } else {
64 if(data)
65 printf("key value = %d \r\n", data);
66 }
67 } else if (ret == 0) { /* 超时 */
68 /* 用户自定义超时处理 */
69 } else if (ret < 0) { /* 错误 */
70 /* 用户自定义错误处理 */
71 }
72 }
73 #endif

        使用 poll 函数来实现非阻塞访问。

75 while (1) {
76 FD_ZERO(&readfds);
77 FD_SET(fd, &readfds);
78 /* 构造超时时间 */
79 timeout.tv_sec = 0;
80 timeout.tv_usec = 500000; /* 500ms */
81 ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
82 switch (ret) {
83 case 0: /* 超时 */
84 /* 用户自定义超时处理 */
85 break;
86 case -1: /* 错误 */
87 /* 用户自定义错误处理 */
88 break;
89 default: /* 可以读取数据 */
90 if(FD_ISSET(fd, &readfds)) {
91 ret = read(fd, &data, sizeof(data));
92 if (ret < 0) {
93 /* 读取错误 */
94 } else {
95 if (data)
96 printf("key value=%d\r\n", data);
97 }
98 }
99 break;
100 }
101 }

        使用 select 函数来实现非阻塞访问。



3.运行测试

1)、编译驱动程序和测试APP

①、编译驱动程序
obj-m := noblockio.o

        make -j32编译成功以后就会生成一个名为“noblockio.ko”的驱动模块文件。

②、编译测试APP
arm-linux-gnueabihf-gcc noblockioApp.c -o noblockioApp

        编译成功以后就会生成 noblcokioApp 这个应用程序。

2)、运行测试

depmod //第一次加载驱动的时候需要运行此命令
modprobe noblockio.ko //加载驱动

驱动加载成功以后使用如下命令打开 noblockioApp 这个测试 APP,并且以后台模式运行:
 

./noblockioApp /dev/noblockio &

        当按下 KEY0 按键以后 noblockioApp 这个测试 APP 就会打印出按键值。输入“top”命令,
查看 noblockioAPP 这个应用 APP 的 CPU 使用率。

四、总结

        本篇笔记为本节的后半部分,主要内容为阻塞IO和非阻塞IO的驱动开发实现。


本文为参考正点原子开发板配套教程整理而得,仅用于学习交流使用,不得用于商业用途。

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

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

相关文章

【排序算法】 归并排序详解!分治思想!

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; 算法—排序篇 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言&#x1f324;️归并排序的思想☁️基本思想☁️归并的思想实现☁️分治法 &#x1f3…

国产芯片vs“国际水平”,有距离也有超越!

当前&#xff0c;国产芯片正在迎来全新的发展阶段。国产终端芯片性能怎么样&#xff0c;与国际主流产品相比&#xff0c;表现如何&#xff1f;今天笔者就针对目前热度较高的四款国产CPU进行参数分析与性能跑分横向对比。 此次国产芯片评测型号分别是海光C86-3250、龙芯3A5000H…

Python 读取 Word 详解(python-docx)

文章目录 1 概述1.1 第三方库&#xff1a;python-docx 2 新建文档2.1 空白文档2.2 标题2.3 段落2.4 文本2.5 字体2.6 图片2.7 表格 3 扩展3.1 修改文档3.2 读取文档 1 概述 1.1 第三方库&#xff1a;python-docx > pip install python-docx2 新建文档 2.1 空白文档 impo…

idea中Run/Debug Python项目报错 Argument for @NotNull parameter ‘module‘ of ...

idea中Run/Debug Python项目报错 Argument for NotNull parameter module of ... idea中运行Python项目main.py时报错&#xff1a; Error running main: Argument for NotNull parameter module of com/intellij/openapi/roots/ModuleRootManager.getInstance must not be nu…

【jenkins】centos7在线安装jenkins

一、系统要求 最低推荐配置 256MB可用内存 1GB可用磁盘空间(作为一个Docker容器运行jenkins的话推荐10GB) 软件配置 Java 8—​无论是Java运行时环境&#xff08;JRE&#xff09;还是Java开发工具包&#xff08;JDK&#xff09;都可以 二、安装jenkins 准备一台安装有ce…

洞察运营机会的数据分析利器

这套分析方法包括5个分析工具&#xff1a; 用“描述性统计”来快速了解数据的整体特点。用“变化分析”来寻找数据的问题和突破口。用“指标体系”来深度洞察变化背后的原因。用“相关性分析”来精确判断原因的影响程度。用“趋势预测”来科学预测未来数据的走势&#xff0c;

系列四十、请谈一下Spring中事务的传播行为

一、概述 事务的传播行为指的是当一个事务方法被另一个事务方法调用时&#xff0c;这个事务方法应该如何进行。事务的传播行为至少发生在两个事务方法的嵌套调用中才会出现。 二、传播行为分类

Mysql进阶-索引篇(下)

SQL性能分析 SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令&#xff0c;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次&#xff0c;通过sql语句的访问频次&#xff0c;我们可…

使用Swift模拟用户登录当网获取数据并保存到MySQL中

前言 当当网作为中国最大的综合性网上商城之一&#xff0c;通过爬取当当网数据&#xff0c;我们可以获取商品信息、用户评价、销售数据等宝贵的信息资源。这些数据可以帮助企业了解市场趋势、分析竞争对手、优化产品定价等&#xff0c;从而做出更明智的决策。 为什么使用Swif…

3D网页游戏外包开发引擎

3D网页开发引擎是用于创建具有三维图形、虚拟现实和交互性的网页应用程序的工具。以下是一些常用的3D网页开发引擎以及它们的主要特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Three.js&…

Mysql设置了更新时间自动更新,指定更新部分sql时不进行时间更新

现象&#xff1a; 因为字段设置了自动更新&#xff0c;所以sql语句一进行修改此字段就会自动更新时间&#xff0c;但是呢我们的有部分定时任务是半夜执行&#xff0c;并且不能让这个任务修改到数据的更新时间 解决&#xff1a; <update id"updateCreative">ALT…

mac安装nodejs,跑vue程序

1. 下载node.js for mac&#xff0c;地址&#xff1a;Node.js。一路安装就可以了&#xff0c;无需修改。 2. mac终端&#xff0c;查看node和npm的版本。 3. 配置环境变量&#xff0c; vim .bash_profile增加PATH$PATH:/usr/local/bin/ 4. 但是毕竟npm安装一些东西还是太慢了所…

【网安AIGC专题10.19】论文6:Java漏洞自动修复+数据集 VJBench+大语言模型、APR技术+代码转换方法+LLM和DL-APR模型的挑战与机会

How Effective Are Neural Networks for Fixing Security Vulnerabilities 写在最前面摘要贡献发现 介绍背景&#xff1a;漏洞修复需求和Java漏洞修复方向动机方法贡献 数据集先前的数据集和Java漏洞Benchmark数据集扩展要求数据处理工作最终数据集 VJBenchVJBench 与 Vul4J 的…

Git基础命令实践

文章目录 简介git的安装配置git的安装git的配置 git使用的基本流程创建版本库时光机穿梭版本回退工作区和暂存区管理修改撤销修改删除文件 远程仓库添加远程库从远程库克隆 总结 简介 本文主要记录了我在学习git操作的过程&#xff0c;以及如何使用GitHub。建议先参考廖雪峰的…

计算机网络_04_传输层

文章目录 1.什么是传输层2.传输层提供了什么服务3.传输层协议TCP 1.什么是传输层 传输层是OSI七层体系架构中的第四层, TCP/IP四层体系架构中的第二层, 从通信和信息处理两方面来看&#xff0c;“传输层”既是面向通信部分的最高层&#xff0c;与下面的三层一起共同构建进行网…

飞利浦双串口51单片机485网关

主要功能将PC端的数据接收下来&#xff0c;分发到不同的设备&#xff0c;也是轮询设备数据读取回来&#xff0c;打包回传到PC端&#xff0c;数据包包头包尾识别&#xff0c;数据校验&#xff0c;接收超时处理&#xff0c;将协议结构化处理&#xff0c;协议的改动不需要改动程序…

【数据结构】Map和Set

Map和Set 1. 搜索树 1.1 概念 二叉搜索树是左子树比根节点小&#xff0c;右子树比根节点大的二叉树。&#xff08;如果左右子树不为空的话是这样&#xff0c;但是左右子树也可以为空&#xff09; 1.2 操作——查找 查找的思想与二分查找类似。 如果根节点的值和所要查找的…

前端知识与基础应用

前端知识 什么是前端&#xff1a;所有和用户打交道的操作页面&#xff0c;我们都称之为前端 例如&#xff1a;pc页面&#xff0c;浏览器的主页面&#xff0c;手机页面等等&#xff0c;可以用肉眼看到的就是前端 什么是后端&#xff1a; 就是一堆代码&#xff0c;用户不能够直接…

Kitex踩坑 [Error] KITEX: processing request error,i/o timeout

报错问题 2023/010/28 17:20:10.250768 default_server_handler.go:234: [Error] KITEX: processing request error, remoteService, remoteAddr127.0.0.1:65425, errordefault codec read failed: read tcp 127.0.0.1:8888->127.0.0.1:65425: i/o timeout 分析原因 Hert…