📄 linux设备驱动程序学习(13)-linux设备模型(总线、设备、驱动程序和类) - linux设备驱动程序 - tekkaman ninja.htm
字号:
<SPAN style="COLOR: rgb(0,0,204)">*</SPAN>
dev<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN
style="COLOR: rgb(255,153,0)">/*处理热插拔、电源管理、探测和移除等事件的方法*/</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,255)">unsigned</SPAN>
<SPAN style="COLOR: rgb(0,0,255)">int</SPAN>
drivers_autoprobe<SPAN
style="COLOR: rgb(0,0,204)">:</SPAN>1<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></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
<P><FONT color=#0000ff
size=3><STRONG>总线的注册和删除</STRONG></FONT></P>
<P>总线的主要注册步骤:</P>
<P>(1)申明和初始化 bus_type 结构体。只有很少的 bus_type
成员需要初始化,大部分都由设备模型核心控制。但必须为总线指定名字及一些必要的方法。例如:
<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>
bus_type ldd_bus_type <SPAN
style="COLOR: rgb(0,0,204)">=</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">{</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,204)">.</SPAN>name <SPAN
style="COLOR: rgb(0,0,204)">=</SPAN> <SPAN
style="COLOR: rgb(255,0,255)">"ldd"</SPAN><SPAN
style="COLOR: rgb(0,0,204)">,</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,204)">.</SPAN>match <SPAN
style="COLOR: rgb(0,0,204)">=</SPAN>
ldd_match<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,204)">.</SPAN>uevent <SPAN
style="COLOR: rgb(0,0,204)">=</SPAN>
ldd_uevent<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></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
<P>(2)调用bus_register函数注册总线。
<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)">int</SPAN>
bus_register<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN>
bus_type <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN> bus<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
<DIV></DIV>
<DIV></DIV>
<DIV><SPAN style="COLOR: rgb(255,153,0)"><FONT
face=新宋体 color=#000000>调用可能失败,
所以必须始终检查返回值。若成功,新的总线子系统将被添加进系统,并可在 sysfs 的
/sys/bus 下看到。之后可以向总线添加设备。</FONT></SPAN></DIV>
<DIV><SPAN style="COLOR: rgb(255,153,0)"><FONT
color=#000000>例如:
<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=新宋体>ret
<SPAN style="COLOR: rgb(0,0,204)">=</SPAN>
bus_register<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,204)">&</SPAN>ldd_bus_type<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN
style="COLOR: rgb(0,0,255)">if</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">(</SPAN>ret<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,255)">return</SPAN>
ret<SPAN style="COLOR: rgb(0,0,204)">;</SPAN>
</FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></FONT></SPAN></DIV>
<DIV><SPAN style="COLOR: rgb(255,153,0)"><FONT
color=#000000></FONT></SPAN> </DIV>
<DIV><SPAN style="COLOR: rgb(255,153,0)"><FONT
color=#000000>当必须从系统中删除一个总线时,
调用:</FONT></SPAN></DIV>
<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>
bus_unregister<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN>
bus_type <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>bus<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE>
<P><FONT color=#0000ff
size=3><STRONG>总线方法</STRONG></FONT></P>
<P>在 bus_type
结构中定义了许多方法,它们允许总线核心作为设备核心和单独的驱动程序之间提供服务的中介,主要介绍以下两个方法:
<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)">int</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>match<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN> device
<SPAN style="COLOR: rgb(0,0,204)">*</SPAN>
dev<SPAN style="COLOR: rgb(0,0,204)">,</SPAN>
<SPAN style="COLOR: rgb(0,0,255)">struct</SPAN>
device_driver <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN> drv<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN
style="COLOR: rgb(255,153,0)">/*当一个新设备或者驱动被添加到这个总线时,这个方法会被调用一次或多次,若指定的驱动程序能够处理指定的设备,则返回非零值。必须在总线层使用这个函数,
因为那里存在正确的逻辑,核心内核不知道如何为每个总线类型匹配设备和驱动程序*/</SPAN><BR><BR><SPAN
style="COLOR: rgb(0,0,255)">int</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>uevent<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN> device
<SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>dev<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">char</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN><SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>envp<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">int</SPAN>
num_envp<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">char</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>buffer<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">int</SPAN>
buffer_size<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN
style="COLOR: rgb(255,153,0)">/*在为用户空间产生热插拔事件之前,这个方法允许总线添加环境变量(参数和
kset
的uevent方法相同)*/</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
<P>lddbus的<FONT face=新宋体>match和uevent方法:</FONT>
<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)">static</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">int</SPAN>
ldd_match<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN> device
<SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>dev<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN>
device_driver <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>driver<SPAN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -