linux设备驱动程序学习(7)-内核的数据类型 - linux设备驱动程序 - tekkaman ninja.htm
来自「Linux设备驱动程序学习(7)-内核的数据类型 - Linux设备驱动程序.r」· HTM 代码 · 共 943 行 · 第 1/5 页
HTM
943 行
style="COLOR: #0000cc">}</SPAN> __attribute__
<SPAN style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000cc">(</SPAN>packed<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE>
<P><PRE style="MARGIN-BOTTOM: 0.5cm"><STRONG><FONT color=#0000ff><FONT size=3><SPAN lang=zh-CN>指针和错误值</SPAN></FONT></FONT></STRONG></PRE>
<P><SPAN
lang=zh-CN>许多内核接口通过将错误值编码到指针值中来返回错误信息。这样的信息必须小心使用,因为它们的返回值不能简单地与
</SPAN><FONT face="Times New Roman, serif"><SPAN
lang=zh-CN>NULL </SPAN></FONT><SPAN
lang=zh-CN>比较。为帮助创建和使用这类接口</SPAN><FONT
face="Times New Roman, serif"><SPAN
lang=zh-CN>, </SPAN><FONT
color=#0000ff><SPAN
lang=zh-CN><linux/err.h></SPAN></FONT></FONT><SPAN
lang=zh-CN>提供了这样的函数:</SPAN></P>
<P>
<TABLE borderColor=#999999 cellSpacing=0
cellPadding=2 width="95%" bgColor=#f1f1f1
border=1>
<COLGROUP>
<COL width=256>
<TBODY>
<TR>
<TD width="100%">
<P
style="MARGIN-TOP: 0.13cm; MARGIN-LEFT: 0.13cm; MARGIN-RIGHT: 0.13cm"><FONT
face=新宋体><CODE><FONT
color=#0000ff>void</FONT></CODE><CODE><FONT
color=#000000> </FONT></CODE><CODE><FONT
color=#0000cc>*</FONT></CODE><CODE><FONT
color=#000000>ERR_PTR</FONT></CODE><CODE><FONT
color=#0000cc>(</FONT></CODE><CODE><FONT
color=#0000ff>long</FONT></CODE><CODE><FONT
color=#000000> </FONT></CODE><CODE><FONT
color=#ff0000>error</FONT></CODE><CODE><FONT
color=#0000cc>);</FONT></CODE><CODE><FONT
color=#ff9900>/*</FONT></CODE></FONT><CODE><FONT
color=#ff9900><FONT
face=新宋体>将错误值编码到指针值中,</FONT><FONT
face="Times New Roman, serif">error
</FONT></CODE></FONT><CODE><FONT
color=#ff9900><FONT
face=新宋体>是常见的负值错误码</FONT><FONT
face="Times New Roman, serif">*/</FONT></CODE><CODE><FONT
color=#000000><BR></FONT></CODE><FONT
face=新宋体><CODE><FONT
color=#0000ff>long</FONT></CODE><CODE><FONT
color=#000000> IS_ERR</FONT></CODE><CODE><FONT
color=#0000cc>(</FONT></CODE><CODE><FONT
color=#0000ff>const</FONT></CODE><CODE><FONT
color=#000000> </FONT></CODE><CODE><FONT
color=#0000ff>void</FONT></CODE><CODE><FONT
color=#000000> </FONT></CODE><CODE><FONT
color=#0000cc>*</FONT></CODE><CODE><FONT
color=#000000>ptr</FONT></CODE><CODE><FONT
color=#0000cc>);</FONT></CODE><CODE><FONT
color=#000000> </FONT></CODE><CODE><FONT
color=#ff9900>/*</FONT></CODE></FONT></FONT><CODE><FONT
color=#ff9900><FONT
face=新宋体>测试返回的指针是不是一个错误码</FONT><FONT
face="Times New Roman, serif">*/</FONT></CODE><CODE><FONT
color=#000000><BR></FONT></CODE><FONT
face=新宋体><CODE><FONT
color=#0000ff>long</FONT></CODE><CODE><FONT
color=#000000> PTR_ERR</FONT></CODE><CODE><FONT
color=#0000cc>(</FONT></CODE><CODE><FONT
color=#0000ff>const</FONT></CODE><CODE><FONT
color=#000000> </FONT></CODE><CODE><FONT
color=#0000ff>void</FONT></CODE><CODE><FONT
color=#000000> </FONT></CODE><CODE><FONT
color=#0000cc>*</FONT></CODE><CODE><FONT
color=#000000>ptr</FONT></CODE><CODE><FONT
color=#0000cc>);</FONT></CODE><CODE><FONT
color=#000000> </FONT></CODE><CODE><FONT
color=#ff9900>/*</FONT></CODE></FONT></FONT><CODE><FONT
color=#ff9900><FONT
face=新宋体>抽取实际的错误码,只有在</FONT><FONT
face="Times New Roman, serif">IS_ERR
</FONT></CODE></FONT><CODE><FONT
color=#ff9900><FONT
face=新宋体>返回一个真值时使用,否则一个有效指针</FONT><FONT
face="Times New Roman, serif">*/</FONT></CODE></FONT></P></TD></TR></TBODY></TABLE>
<HR>
<P><STRONG><FONT color=#0000ff><FONT
size=4>链表</FONT></FONT></STRONG></P>
<P>操作系统内核常需要维护数据结构的链表。<FONT
face="Times New Roman, serif">Linux
</FONT>内核已经同时有几个链表实现。为减少复制代码的数量<FONT
face="Times New Roman, serif">,
</FONT>内核已经创建了一个标准环形双向链表,并鼓励需要操作链表的人使用这个设施<FONT
face="Times New Roman, serif">.</FONT></P>
<P>使用链表接口时,应当记住列表函数没做加锁。若驱动可能同一个列表并发操作,就必须实现一个锁方案。</P>
<P style="MARGIN-BOTTOM: 0cm">为使用链表机制,驱动必须包含文件
<FONT
face="Times New Roman, serif"><linux/list.h>
</FONT>,它定义了一个简单的<FONT
face="Times New Roman, serif">list_head </FONT>类型
结构<FONT face="Times New Roman, serif">:
</FONT></P>
<P>
<TABLE borderColor=#999999 cellSpacing=0
cellPadding=2 width="95%" bgColor=#f1f1f1
border=1>
<COLGROUP>
<COL width=256>
<TBODY>
<TR>
<TD width="100%">
<P
style="MARGIN-TOP: 0.13cm; MARGIN-LEFT: 0.13cm; MARGIN-RIGHT: 0.13cm"><FONT
face="Times New Roman, serif"><CODE><FONT
color=#0000ff><FONT
face=新宋体>struct</FONT></FONT></CODE><CODE><FONT
color=#000000><FONT face=新宋体> list_head
</FONT></FONT></CODE><CODE><FONT
color=#0000cc><FONT
face=新宋体>{</FONT></FONT></CODE><CODE><FONT
color=#000000><FONT face=新宋体>
</FONT></FONT></CODE><CODE><FONT
color=#0000ff><FONT
face=新宋体>struct</FONT></FONT></CODE><CODE><FONT
color=#000000><FONT face=新宋体> list_head
</FONT></FONT></CODE><CODE><FONT
color=#0000cc><FONT
face=新宋体>*</FONT></FONT></CODE><CODE><FONT
color=#000000><FONT
face=新宋体>next</FONT></FONT></CODE><CODE><FONT
color=#0000cc><FONT
face=新宋体>,</FONT></FONT></CODE><CODE><FONT
color=#000000><FONT face=新宋体>
</FONT></FONT></CODE><CODE><FONT
color=#0000cc><FONT
face=新宋体>*</FONT></FONT></CODE><CODE><FONT
color=#000000><FONT
face=新宋体>prev</FONT></FONT></CODE><CODE><FONT
color=#0000cc><FONT
face=新宋体>;</FONT></FONT></CODE><CODE><FONT
color=#000000><FONT face=新宋体>
</FONT></FONT></CODE><CODE><FONT
color=#0000cc><FONT
face=新宋体>};</FONT></FONT></CODE><CODE><FONT
color=#000000><FONT face=新宋体>
</FONT></FONT></CODE></FONT></P></TD></TR></TBODY></TABLE>
<P>实际代码中使用的链表几乎总是由某个结构类型组成<FONT
face="Times New Roman, serif">,
</FONT>每个结构描述链表中的一项<FONT
face="Times New Roman, serif">. </FONT>为使用 <FONT
face="Times New Roman, serif">Linux
</FONT>链表,只需嵌入一个 <FONT
face="Times New Roman, serif">list_head
</FONT>在构成在这个链表的结构里面。链表头常常是一个独立的 <FONT
face="Times New Roman, serif">list_head
</FONT>结构。下图显示了这个简单的 <FONT
face="Times New Roman, serif">struct list_head
</FONT>是如何用来维护一个数据结构的列表的<FONT
face="Times New Roman, serif">.</FONT></P>
<P style="MARGIN-BOTTOM: 0cm"><IMG
style="WIDTH: 554px; HEIGHT: 332px" height=38
alt=链表头数据结构
src="Linux设备驱动程序学习(7)-内核的数据类型 - Linux设备驱动程序 - Tekkaman Ninja.files/ldd3-11-1.png"
width=75 align=bottom border=0 name=图形1> </P>
<P>
<TABLE borderColor=#999999 cellSpacing=0
cellPadding=2 width="95%" bgColor=#f1f1f1
border=1>
<COLGROUP>
<COL width=256>
<TBODY>
<TR>
<TD width="100%">
<P
style="MARGIN-TOP: 0.13cm; MARGIN-LEFT: 0.13cm; MARGIN-RIGHT: 0.13cm"><CODE><FONT
face=新宋体
color=#ff9900>/*</FONT></CODE><CODE><FONT
color=#ff9900><FONT
face=新宋体>链表头必须在使用前初始化</FONT><FONT
face="Times New Roman, serif">,</FONT></CODE></FONT><CODE><FONT
color=#ff9900><FONT face=新宋体>有两种形式: </FONT><FONT
face="Times New Roman, serif">*/</FONT></CODE><CODE><FONT
color=#000000><BR></FONT></CODE><CODE><FONT
face=新宋体
color=#ff9900>/*</FONT></CODE></FONT><CODE><FONT
color=#ff9900><FONT
face=新宋体>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?