linux设备驱动程序学习(7)-内核的数据类型 - linux设备驱动程序 - tekkaman ninja.htm
来自「Linux设备驱动程序学习(7)-内核的数据类型 - Linux设备驱动程序.r」· HTM 代码 · 共 943 行 · 第 1/5 页
HTM
943 行
style="COLOR: #0000cc">><FONT
color=#000000>中定义了</FONT></SPAN></FONT>__LITTLE_ENDIAN,这些依赖处理器的字节序当处理字节序问题时,需要编码一堆类似
#ifdef __LITTTLE_ENDIAN 的条件语句。</P>
<P>但是还有一个更好的方法:Linux
内核有一套宏定义来处理处理器字节序和特定字节序之间的转换。例如:
<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: #000000"><FONT face=新宋体>u32
cpu_to_le32 <SPAN
style="COLOR: #0000cc">(</SPAN>u32<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR>u32
le32_to_cpu <SPAN
style="COLOR: #0000cc">(</SPAN>u32<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR><SPAN
style="COLOR: #ff9900">/*这些宏定义将一个CPU使用的值转换成一个无符号的32位小头数值,无论
CPU 是大端还是小端,也不管是不是32
位处理器。在没有转换工作需要做时,返回未修改的值。*/</SPAN><BR><BR><SPAN
style="COLOR: #ff9900">/*有很多类似的函数在
<linux/byteorder/big_endian.h> 和
<linux/byteorder/little_endian.h>
中定义*/</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P><PRE class=programlisting> </PRE><PRE class=programlisting><FONT color=#0000ff size=3><STRONG>数据对齐</STRONG></FONT></PRE></DIV>
<DIV class=sect2 lang=zh-cn>
<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: #000000"><FONT face=新宋体><SPAN
style="COLOR: #0000cc">#</SPAN><SPAN
style="COLOR: #ff0000">include</SPAN> <SPAN
style="COLOR: #0000cc"><</SPAN><SPAN
style="COLOR: #0000ff">asm</SPAN><SPAN
style="COLOR: #0000cc">/</SPAN>unaligned<SPAN
style="COLOR: #0000cc">.</SPAN>h<SPAN
style="COLOR: #0000cc">></SPAN><BR>get_unaligned<SPAN
style="COLOR: #0000cc">(</SPAN>ptr<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR>put_unaligned<SPAN
style="COLOR: #0000cc">(</SPAN>val<SPAN
style="COLOR: #0000cc">,</SPAN> ptr<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE>这些宏是无类型的,并对各总数据项,不管是
1、2、4或 8 个字节,他们都有效,并且在所有内核版本中都有定义。</P>
<P>关于对齐的另一个问题是数据结构的跨平台移植性。同样的数据结构在不同的平台上可能被不同地编译。为了编写可以跨体系移植的数据结构,应当始终强制数据项的自然对齐。自然对齐(natural
alignment)指的是:数据项大小的整数倍的地址上存储数据项。
应当使用填充符避免强制自然对齐时编译器移动数据结构的字段,在数据结构中留下空洞。</P>
<P>dataalign 程序实验展示了编译器如何强制对齐。</P>
<P>为了目标处理器的良好性能,编译器可能悄悄地插入填充符到结构中,来保证每个成员是对齐的。若定义一个和设备要求的结构体相匹配结构,自动填充符会破坏这个意图。解决这个问题的方法是告诉编译器这个结构必须是"紧凑的",
不能增加填充符。例如下列的定义:</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: #000000"><FONT face=新宋体><SPAN
style="COLOR: #0000ff">struct</SPAN><BR><SPAN
style="COLOR: #0000cc">{</SPAN><BR> u16
id<SPAN
style="COLOR: #0000cc">;</SPAN><BR> u64
lun<SPAN
style="COLOR: #0000cc">;</SPAN><BR> u16
reserved1<SPAN
style="COLOR: #0000cc">;</SPAN><BR> u32
reserved2<SPAN
style="COLOR: #0000cc">;</SPAN><BR><SPAN
style="COLOR: #0000cc">}</SPAN><BR>__attribute__
<SPAN style="COLOR: #0000cc">(</SPAN><SPAN
style="COLOR: #0000cc">(</SPAN>packed<SPAN
style="COLOR: #0000cc">)</SPAN><SPAN
style="COLOR: #0000cc">)</SPAN> scsi<SPAN
style="COLOR: #0000cc">;</SPAN><BR><BR><SPAN
style="COLOR: #ff9900">/*如果在 64-位平台上编译这个结构,若没有
__attribute__ ((packed)), lun 成员可能在前面被添加 2 个或 6
个填充符字节。指针和错误值*/</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
<P>你还可以在利用ARM9和USB摄像头进行视频采集的servfox源代码的spcaframe.h头文件中找到这种方法的实际应用:
<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: #000000"><FONT face=新宋体><SPAN
style="COLOR: #0000ff">struct</SPAN>
frame_t<SPAN
style="COLOR: #0000cc">{</SPAN><BR> <SPAN
style="COLOR: #0000ff">char</SPAN> header<SPAN
style="COLOR: #0000cc">[</SPAN>5<SPAN
style="COLOR: #0000cc">]</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">int</SPAN> nbframe<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">double</SPAN>
seqtimes<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">int</SPAN>
deltatimes<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">int</SPAN> w<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">int</SPAN> h<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">int</SPAN> size<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">int</SPAN> format<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">short</SPAN> bright<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">short</SPAN>
contrast<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">short</SPAN> colors<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">short</SPAN>
exposure<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN> wakeup<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">int</SPAN>
acknowledge<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
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> <BR><SPAN
style="COLOR: #0000ff">struct</SPAN>
client_t<SPAN
style="COLOR: #0000cc">{</SPAN><BR> <SPAN
style="COLOR: #0000ff">char</SPAN> message<SPAN
style="COLOR: #0000cc">[</SPAN>4<SPAN
style="COLOR: #0000cc">]</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN> x<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN> y<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN> fps<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN>
updobright<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN>
updocontrast<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN>
updocolors<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN>
updoexposure<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN> updosize<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
style="COLOR: #0000ff">unsigned</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN> sleepon<SPAN
style="COLOR: #0000cc">;</SPAN><BR> <SPAN
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?