⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux设备驱动程序学习(5)-高级字符驱动程序操作[(2)阻塞型i-o和休眠] - linux设备驱动程序 - tekkaman ninja.htm

📁 Linux设备驱动程序学习(5)-高级字符驱动程序操作[(2)阻塞型I-O和休眠] - Linux设备驱动程序.rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                              color=#0000ff>如果驱动程序无法立即满足请求,该如何响应?(65865346)</FONT></P>
                              <P align=center>
                              <HR id=null>

                              <P></P>
                              <P align=left><FONT color=#0000ff 
                              size=5><STRONG>一、休眠</STRONG></FONT></P>
                              <P>进程被置为休眠,意味着它被标识为处于一个特殊的状态并且从调度器的运行队列中移走。这个进程将不被在任何 
                              CPU 上调度,即将不会运行。 直到发生某些事情改变了那个状态。安全地进入休眠的两条规则:</P>
                              <P>(1) 永远不要在原子上下文中进入休眠,即<FONT 
                              color=#0000ff>当驱动在持有一个自旋锁、seqlock或者 RCU 
                              锁时不能睡眠;关闭中断也不能睡眠。</FONT>持有一个信号量时休眠是合法的,但你应当仔细查看代码:如果代码在持有一个信号量时睡眠,任何其他的等待这个信号量的线程也会休眠。因此发生在持有信号量时的休眠必须短暂,而且决不能阻塞那个将最终唤醒你的进程。</P>
                              <P>(2)当进程被唤醒,它并不知道休眠了多长时间以及休眠时发生什么;也不知道是否另有进程也在休眠等待同一事件,且那个进程可能在它之前醒来并获取了所等待的资源。所以不能对唤醒后的系统状态做任何的假设,并<FONT 
                              color=#ff0000>必须重新检查等待条件来确保正确的响应</FONT>。</P>
                              <P><FONT 
                              size=3>除非确信其他进程会在其他地方唤醒休眠的进程,否则也不能睡眠。使进程可被找到意味着:需要维护一个称为等待队列的数据结构。它是一个进程链表,其中饱含了等待某个特定事件的所有进程。在 
                              Linux 中, 一个等待队列由一个wait_queue_head_t 
                              结构体来管理,其定义在<FONT 
                              color=#0000ff>&lt;linux/wait.h&gt;</FONT>中。</FONT>wait_queue_head_t 
                              类型的数据结构非常简单: </P>
                              <P>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><FONT face=新宋体><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                __wait_queue_head <SPAN 
                                style="COLOR: rgb(0,0,204)">{</SPAN><BR>&nbsp;&nbsp;&nbsp;&nbsp;spinlock_t 
                                lock<SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR>&nbsp;&nbsp;&nbsp;&nbsp;<SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                list_head task_list<SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,204)">}</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">typedef</SPAN> <SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                __wait_queue_head wait_queue_head_t<SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
                              <P>它包含一个自旋锁和一个链表。这个链表是一个等待队列入口,它被声明做 
                              wait_queue_t。wait_queue_head_t包含关于睡眠进程的信息和它想怎样被唤醒。 
                              </P>
                              <P>
                              <HR id=null>

                              <P></P>
                              <P></P>
                              <P></P>
                              <P><FONT color=#0000ff 
                              size=4><STRONG>简单休眠(其实是高级休眠的宏)</STRONG></FONT></P>
                              <P><FONT size=4>Linux 内核中最简单的休眠方式是称为 
                              wait_event的宏</FONT><FONT 
                              size=4>(及其变种),它实现了休眠和进程等待的条件的检查。形式如下:</FONT></P>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)">wait_event<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(255,0,0)">queue</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> 
                                condition<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/*不可中断休眠,不推荐*/</SPAN><BR>wait_event_interruptible<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(255,0,0)">queue</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> 
                                condition<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/*推荐,返回非零值意味着休眠被中断,且驱动应返回 
                                -ERESTARTSYS*/</SPAN><BR>wait_event_timeout<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(255,0,0)">queue</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> 
                                condition<SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> 
                                timeout<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><BR>wait_event_interruptible_timeout<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(255,0,0)">queue</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> 
                                condition<SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> 
                                timeout<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><BR><SPAN 
                                style="COLOR: rgb(255,153,0)">/*有限的时间的休眠;若超时,<FONT 
                                face=新宋体>则不管条件为何值</FONT>返回0,*/</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE>
                              <P>唤醒休眠进程的函数称为 wake_up,形式如下:</P>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                wake_up<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>wait_queue_head_t 
                                <SPAN style="COLOR: rgb(0,0,204)">*</SPAN><SPAN 
                                style="COLOR: rgb(255,0,0)">queue</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                wake_up_interruptible<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>wait_queue_head_t 
                                <SPAN style="COLOR: rgb(0,0,204)">*</SPAN><SPAN 
                                style="COLOR: rgb(255,0,0)">queue</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE>
                              <P>惯例:用 wake_up&nbsp;唤醒 wait_event ;用 
                              wake_up_interruptible 
                              唤醒wait_event_interruptible。</P>
                              <P><FONT size=4><SPAN 
                              style="COLOR: rgb(0,1,255)">简单休眠实验</SPAN></FONT><BR>&nbsp;<FONT 
                              color=#ff0000 size=3><FONT face=新宋体><FONT 
                              color=#000000 
                              size=3>模块程序链接:</FONT></FONT></FONT><A 
                              href="http://blogimg.chinaunix.net/blog/upfile2/071102165236.gz" 
                              target=_blank>sleepy</A><BR><FONT 
                              size=3>模块测试程序</FONT><FONT color=#ff0000 
                              size=3><FONT face=新宋体><FONT color=#000000 
                              size=3>链接</FONT></FONT></FONT><FONT 
                              size=3>:</FONT><A 
                              href="http://blogimg.chinaunix.net/blog/upfile2/071102165157.gz" 
                              target=_blank>sleepy-test</A><SPAN 
                              style="TEXT-DECORATION: underline"></SPAN></P>
                              <P><FONT size=3><SPAN 
                              style="COLOR: rgb(0,1,255)">实验现象:</SPAN></FONT><BR></P>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><SPAN 
                                style="COLOR: rgb(0,0,204)">[</SPAN>Tekkaman2440@SBC2440V4<SPAN 
                                style="COLOR: rgb(0,0,204)">]</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">#</SPAN>cd <SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>lib<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>modules<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,204)">[</SPAN>Tekkaman2440@SBC2440V4<SPAN 
                                style="COLOR: rgb(0,0,204)">]</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">#</SPAN>insmod 
                                sleepy<SPAN 
                                style="COLOR: rgb(0,0,204)">.</SPAN>ko<BR><SPAN 
                                style="COLOR: rgb(0,0,204)">[</SPAN>Tekkaman2440@SBC2440V4<SPAN 
                                style="COLOR: rgb(0,0,204)">]</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">#</SPAN>cd <SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>dev<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,204)">[</SPAN>Tekkaman2440@SBC2440V4<SPAN 
                                style="COLOR: rgb(0,0,204)">]</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">#</SPAN>cat <SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>proc<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>devices<BR>Character 
                                devices<SPAN 
                                style="COLOR: rgb(0,0,204)">:</SPAN><BR>&nbsp;&nbsp;1 
                                mem<BR>&nbsp;&nbsp;2 pty<BR>&nbsp;&nbsp;3 
                                ttyp<BR>&nbsp;&nbsp;4 <SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>dev<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>vc<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>0<BR>&nbsp;&nbsp;4 
                                tty<BR>&nbsp;&nbsp;4 ttyS<BR>&nbsp;&nbsp;5 <SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>dev<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>tty<BR>&nbsp;&nbsp;5 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>dev<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>console<BR>&nbsp;&nbsp;5 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>dev<SPAN 
                                style="COLOR: rgb(0,0,204)">/</SPAN>ptmx<BR>&nbsp;&nbsp;7 
                                vcs<BR>&nbsp;10 misc<BR>&nbsp;13 
                                input<BR>&nbsp;14 sound<BR>&nbsp;81 
                                video4linux<BR>&nbsp;89 i2c<BR>&nbsp;90 
                                mtd<BR>116 alsa<BR>128 ptm<BR>136 pts<BR>180 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -