Linux驱动2_总线设备(一)
来源:互联网 发布:阿里云cdn加速设置 编辑:程序博客网 时间:2024/06/10 08:52
//参考Linux设备驱动程序(lld3)//实现一个简单的虚拟总线 simple bus//simple_bus_type为总线类型//simple_bus为总线设备////simple.c 实现#include "simple.h"//增加设备引用计数static struct simple_device *simple_dev_get(struct simple_device *dev){if (dev)get_device(&dev->device);return dev;}//递减设备引用计数static void simple_dev_put(struct simple_device *dev){if (dev)put_device(&dev->device);}//匹配设备/驱动//当有新设备或新驱动添加到总线时,判断是否匹配//调用路径:核心设备子系统->static int simple_device_match(struct device *dev, struct device_driver *drv){struct simple_device *sim_dev = to_simple_device(dev);struct simple_driver *sim_drv = to_simple_driver(drv);struct simple_class_id *ids = sim_drv->classes;if (ids)while (ids->class_id != SIMPLE_CLASS_END){if (ids->class_id == sim_dev->class_id.class_id)return 1;ids++;}return 0;}//添加设备/驱动//当simple_device_match返回true,说明device和driver匹配,通过//调用probe调用驱动的probe函数,初始化设备//调用路径:核心设备子系统->static int simple_device_probe(struct device *dev){int ret = 0;struct simple_device *sim_dev;struct simple_driver *sim_drv;sim_dev = to_simple_device(dev);sim_drv = to_simple_driver(dev->driver);simple_dev_get(sim_dev);if (sim_drv->probe)ret = sim_drv->probe(sim_dev);if (ret)simple_dev_put(sim_dev);return ret;}//热插拔设备//总线上设备被热插拔//调用路径:核心设备子系统->static int simple_device_remove(struct device *dev){struct simple_device *sim_dev = to_simple_device(dev);struct simple_driver *sim_drv = to_simple_driver(dev->driver);if (sim_drv){if (sim_drv->remove){sim_drv->remove(sim_dev);}}simple_dev_put(sim_dev);return 0;}//获取设备class idstatic ssize_t simple_device_show_class_id(struct device *dev, struct device_attribute *attr, char *buf){struct simple_device *sim_dev = to_simple_device(dev);sprintf(buf, "0x%x\n", sim_dev->class_id.class_id);return strlen(buf) + 1;}//simple bus 设备属性struct device_attribute simple_device_attrs[] = {__ATTR(class_id, S_IRUGO, simple_device_show_class_id, NULL),__ATTR_NULL};//simple bus 总线类型struct bus_type simple_bus_type = {.name = "simple",.match = simple_device_match,.probe = simple_device_probe,.remove = simple_device_remove,.dev_attrs = simple_device_attrs };static void simple_bus_release(struct device *dev){return;}//simple bus 总线设备struct simple_bus simple_bus;//simple bus 模块初始化static int __init simple_init(void){ int ret; /* create /sys/bus/simple.*/ if ((ret = bus_register(&simple_bus_type)) < 0) { printk(KERN_ALERT "[SIMPLE] bus_register failed.\n"); goto err_bus_register; } simple_bus.dev.release = simple_bus_release; //simple_bus.dev.parent为null,表示为该总线的顶层设备 dev_set_name(&simple_bus.dev, "simple"); /* create /sys/devices/simple.*/ if ((ret = device_register(&simple_bus.dev))) { printk(KERN_ALERT "[SIMPLE] device_register failed.\n"); goto err_dev_register; } return ret;err_dev_register:bus_unregister(&simple_bus_type);err_bus_register:return ret;}//simple bus 模块卸载static void __exit simple_exit(void){device_unregister(&simple_bus.dev);bus_unregister(&simple_bus_type);}static void simple_device_release(struct device *dev){return;}//注册设备//向simple bus注册设备int simple_register_device(struct simple_device *dev){dev_set_name(&dev->device, dev->name);//设备类型为实现的simple_bus_typedev->device.bus = &simple_bus_type;//挂载的总线为simple_busdev->device.parent = &simple_bus.dev; dev->device.release = simple_device_release;return device_register(&dev->device);}EXPORT_SYMBOL(simple_register_device);//注销设备//从simple bus注销设备void simple_unregister_device(struct simple_device *dev){/* *device_unregister will do in two parts, first, remove it from all the subsystems with device_del(), *then decrement the reference count via put_device(). If that is the final reference count, *the device will be cleaned up via device_release() above. Otherwise, the structure will stick *around until the final reference to the device is dropped. */device_unregister(&dev->device);} EXPORT_SYMBOL(simple_unregister_device);//注册驱动//向simple bus注册驱动int simple_register_driver(struct simple_driver *drv){int ret = 0;drv->driver.name= drv->name;drv->driver.bus = &simple_bus_type;ret = driver_register(&drv->driver);return ret;}EXPORT_SYMBOL(simple_register_driver);//注销驱动//从simple bus注销驱动void simple_unregister_driver(struct simple_driver *drv){driver_unregister(&drv->driver);}EXPORT_SYMBOL(simple_unregister_driver);module_init(simple_init);module_exit(simple_exit);MODULE_LICENSE("GPL");
//simple.h,类型声明#include <linux/init.h>#include <linux/module.h>#include <linux/device.h>#ifndef _SIMPLE_BUS_H_#define _SIMPLE_BUS_H_#define to_simple_device(dev) container_of(dev, struct simple_device, device)#define to_simple_driver(drv) container_of(drv, struct simple_driver, driver)#define SIMPLE_CLASS_END 0xffffstruct simple_class_id{u16 class_id;};struct simple_device{char *name;struct device device;struct simple_class_id class_id;};struct simple_driver{char *name;struct device_driver driver;struct simple_class_id *classes;int (*probe) (struct simple_device *dev);/*Device removed (NULL if not a hot-plug capable driver) */int (*remove) (struct simple_device *dev);};struct simple_bus{struct device dev;};extern int simple_register_device(struct simple_device *dev);extern void simple_unregister_device(struct simple_device *dev);extern int simple_register_driver(struct simple_driver *drv);extern void simple_unregister_driver(struct simple_driver *drv);#endif
1 0
- Linux驱动2_总线设备(一)
- Linux驱动3_总线设备(二)
- LINUX设备驱动之serio总线(一)
- LINUX设备驱动之serio总线(一)
- Linux总线设备驱动
- linux 总线 设备 驱动
- (三) 总线_设备_驱动注册
- Linux下DM644x设备驱动I2C之总线驱动(一)详解
- linux设备驱动之总线、设备、驱动
- Linux设备驱动,总线,设备,驱动区别
- linux设备驱动之总线,设备,驱动
- linux设备驱动之总线、设备、驱动
- linux设备驱动之总线、设备、驱动
- 迅为Linux驱动教程——总线_设备_驱动注册流程详解
- Linux设备驱动---OMAP3630 Linux I2C总线驱动分析(2)
- Linux I2C核心、总线与设备驱动(一)
- linux总线,设备,驱动注册
- LInux总线,设备和驱动
- MATLAB基本操作(二):数组中操作
- μC/OS之OSTaskCreate()
- redhat5配置yum源
- Reverse Integer
- 黑马程序员--字符串总结
- Linux驱动2_总线设备(一)
- 门面模式——Head First Design Patterns
- 非法触摸的解决方案
- 黑马程序员-StringBuffer和集合
- JBPM基础知识
- c编程常见错误
- 选择广州传智播客.Net培训让我重新走出阴霾
- coreutils学习——单独编译源码
- base64加密 or base64编码?