linux设备驱动归纳总结(八):4.总线热插拔

原文地址:linux设备驱动归纳总结(八):4.总线热插拔
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3631836&fromuid=28801784
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

上一节介绍设备管理中的分层思想和面向对象思想(名字是我自己瞎编的)。接下来说一下热插拔的操作。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


一、热插拔的实现


我不知道在这里用热插拔这样的名字是否合适,在之前的代码,需要我自己手动去加载驱动和设备的模块,但在现实的情况下,一般是当设备一被插入,系统自己会注册设备,并调用合适的驱动。

所以,接下来我要实现的是,在加载了usb总线和usb鼠标驱动的前提下,当有usb鼠标插入,系统自己进行设备的操作。当然,上面的usb鼠标是我自己想象出来的,当我一按下按键(对应中断E_INT1),就代表有usb鼠标插入。

这样看来,要实现的代码就简单,稍稍修改一下程序就可以了,将之前由devie.ko实现的操作交由中断处理函数来执行,当我按下按键,触发中断自动执行


driver.c不用修改,并且把device.c删掉,将代码移到bus.c中:

/*8th_devModule_4/1st/bus.c*/

9 struct work_struct my_work; 

。。。。。

56 /************** 

57 * 设备注册 

58 *************/ 

59 void usb_dev_release(struct device *dev) //卸载函数没有干具体的事情 

60 { 

61     printk("<kernel> release\n"); 

62 } 

63 /*结构体中不需要指定总线的成员,交由usb_device_register来完成*/ 

64 struct usb_device mouse_dev = { 

65     .dev = { 

66         .bus_id = "usb_mouse", 

67         .release = usb_dev_release, 

68     }, 

69 }; 

70 

71 irqreturn_t hotplug_handler(int irqno, void *dev_id) 

72 { 

73     printk("usb mouse device insert\n"); 

74     schedule_work(&my_work); //调度到中断下半部执行 

75     return IRQ_HANDLED; 

76 } 

77 void work_func(struct work_struct *work)//中断下半部处理函数 

78 { 

79     /*假设从硬件读取厂商编号和设备编号*/ 

80     mouse_dev.VendorID = 0x1122; 

81     mouse_dev.DeviceID = 0x3344; 

82     /*在中断函数中注册设备*/ 

83     usb_device_register(&mouse_dev); 

84 } 

85 

86 static int __init usb_bus_init(void) 

87 { 

88     int ret; 

89     /*初始化中断下文struct work_struct为工作队列类型*/ 

90     INIT_WORK(&my_work, work_func); 


91     /*设置IRQ_EINT1的中断*/ 

92     ret = request_irq(IRQ_EINT1, hotplug_handler, IRQF_TRIGGER_FALLING, "usb irq", NULL);

93     if(ret){ 

94         printk("irq failed\n"); 

95         return ret; 

96     } 

97 

98       /*总线注册,必须检测返回值*/ 

99       ret = bus_register(&usb_bus); 

100     if(ret){ 

101         printk("bus register failed!\n"); 

102         return ret; 

103     } 

104 

105     printk("usb bus init\n"); 

106     return 0; 

107 } 

108 

109 static void __exit usb_bus_exit(void) 

110 { 

111     bus_unregister(&usb_bus); 

112     free_irq(IRQ_EINT1, NULL); //释放IRQ_EINT1的中断源 

113     printk("usb bus bye!\n"); 

114 } 

上面的代码可以看到,函数将原来在device.c中实现的操作放在了中断函数来执行,一旦usb鼠标被插入(这里是我假设的,其实就是按下按键,触发E_INT1中断),就会执行注册设备的操作。

看效果:

[root: 1st]# insmod bus.ko //先加载总线

usb bus init

[root: 1st]# insmod driver.ko //再加载驱动

usb driver init

[root: 1st]# usb mouse device insert //当我按下按键,触发中断,假设鼠标被插入

match success //配对成功

init usb mouse //初始化设备

当然,我的函数很多的bug,譬如你再次按下按键,那就会出现错误。但撇来这些不考虑,基本效果就出来了,当设备一插入,内核自动注册设备。


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


二、总结


第八章的设备模型基本上就介绍完了,我在这里没有介绍kobject、kset等这一类内核中用于管理设备模型的结构体,有兴趣可以自己去看看。

接着就会介绍平台类总线设备,到时候你会发现,平台类总线设备其实就是总线的一个封装。


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值