总线,设备,驱动(基于2.6.30.4内核的)
来源:互联网 发布:c语言多线程编程实例 编辑:程序博客网 时间:2024/06/09 19:17
最近在学习总线、设备、驱动程序,编写总线设备驱动程序的时候,发现2.6.30.4内核中的struct device已经没有bus_id的成员了,发现了const char *init_name成员。但是,这个成员是不能直接用来设置和读取设备名的。通过查阅资料发现2.6.30.4的内核中对struct device属性的bus_id应经修改了,感觉这挺好的,最起码不会差生歧异。下面的2.6.30.4内核上所做的改变:
内核操作的方法为dev_name和dev_set_name。内核中的定义是:
1) dev_name
static inline const char *dev_name(const struct device *dev)
{
return kobject_name(&dev->kobj);
}
2) dev_set_name
/**
* dev_set_name - set a device name
* @dev: device
* @fmt: format string for the device's name
*/
int dev_set_name(struct device *dev, const char *fmt, ...)
{
va_list vargs;
int err;
va_start(vargs, fmt);
err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
va_end(vargs);
return err;
}
EXPORT_SYMBOL_GPL(dev_set_name);
总线
总线是处理器和一个或多个设备之间的通道,在设备模型中, 所有的设备都通过总线相连, 甚至是内部的虚拟"platform"总线。总线可以相互插入。设备模型展示了总线和它们所控制的设备之间的实际连接。
在 Linux 设备模型中, 总线由 bus_type 结构表示, 定义在 <linux/device.h>,创建一条总线的实例 :
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
MODULE_AUTHOR("sjwangjinbao");
MODULE_LICENSE("Dual BSD/GPL");
static char *Version = "$Revision: 1.0 $";
static int my_match(struct device *dev, struct device_driver *driver)
{
return !strncmp(dev_name(dev), driver->name, strlen(driver->name) );
}
static void my_bus_release(struct device *dev)
{
printk("my bus release/n");
}
struct device my_bus = {
.release = my_bus_release
};
struct bus_type my_bus_type = {
.name = "my_bus",
.match = my_match,
};
EXPORT_SYMBOL(my_bus);
EXPORT_SYMBOL(my_bus_type);
/*
* Export a simple attribute.
*/
static ssize_t show_bus_version(struct bus_type *bus, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s/n", Version);
}
static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);
static int __init my_bus_init(void)
{
int ret;
/*注册总线*/
ret = bus_register(&my_bus_type);
if (ret)
{
return ret;
}
/*创建属性文件*/
if (bus_create_file(&my_bus_type, &bus_attr_version))
{
printk("Fail to create version attribute!/n");
}
/*初始化总线设备*/
dev_set_name(&my_bus, "my_bus0");
/*注册总线设备*/
ret = device_register(&my_bus);
if (ret)
{
printk("Fail to register device:my_bus!/n");
}
return ret;
}
static void my_bus_exit(void)
{
device_unregister(&my_bus);
bus_unregister(&my_bus_type);
}
module_init(my_bus_init);
module_exit(my_bus_exit);
设备
在最底层, Linux 系统中的每个设备由一个 struct device 代表,内核创建一个设备的方实例:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
MODULE_AUTHOR("sjwangjinbao");
MODULE_LICENSE("Dual BSD/GPL");
extern struct device my_bus;
extern struct bus_type my_bus_type;
static void my_dev_release(struct device *dev)
{
}
struct device my_dev = {
.bus = &my_bus_type,
.parent = &my_bus,
.release = my_dev_release,
};
/*
* Export a simple attribute.
*/
static ssize_t mydev_show(struct device *dev,struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s/n", "This is sjwangjinbao device!");
}
static DEVICE_ATTR(dev, S_IRUGO, mydev_show, NULL);
static int __init my_device_init(void)
{
int ret = 0;
/*初始化设备*/
dev_set_name(&my_dev, "my_dev");
/*注册设备*/
device_register(&my_dev);
/*创建属性文件*/
device_create_file(&my_dev, &dev_attr_dev);
return ret;
}
static void my_device_exit(void)
{
device_unregister(&my_dev);
}
module_init(my_device_init);
module_exit(my_device_exit);
驱动
在最底层, Linux 系统中的每个设备驱动程序由device_driver表示,在内核建立驱动文件测试程序代码如下
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
MODULE_AUTHOR("David Xie");
MODULE_LICENSE("Dual BSD/GPL");
extern struct bus_type my_bus_type;
static int my_probe(struct device *dev)
{
printk("Driver found device which my driver can handle!\n");
return 0;
}
static int my_remove(struct device *dev)
{
printk("Driver found device unpluged!\n");
return 0;
}
struct device_driver my_driver = {
.name = "my_dev",
.bus = &my_bus_type,
.probe = my_probe,
.remove = my_remove,
};
/*
* Export a simple attribute.
*/
static ssize_t mydriver_show(struct device_driver *driver, char *buf)
{
return sprintf(buf, "%s\n", "This is my driver!");
}
static DRIVER_ATTR(drv, S_IRUGO, mydriver_show, NULL);
static int __init my_driver_init(void)
{
int ret = 0;
/*注册驱动*/
driver_register(&my_driver);
/*创建属性文件*/
driver_create_file(&my_driver, &driver_attr_drv);
return ret;
}
static void my_driver_exit(void)
{
driver_unregister(&my_driver);
}
module_init(my_driver_init);
module_exit(my_driver_exit);
- 总线,设备,驱动(基于2.6.30.4内核的)
- Linux内核设备、驱动和总线的概念
- 基于platform总线的mini2440的led设备驱动例子
- 基于platform总线的中断(按键)字符设备驱动设计
- 基于platform总线的中断(按键)字符设备驱动设计
- 基于platform总线的中断(按键)字符设备驱动设计
- 基于 platform 总线的设备驱动编写模式:
- 基于platform总线的中断(按键)字符设备驱动设计
- 基于Linux内核的1-wair总线驱动
- 基于Linux内核的1-wair总线驱动(…
- 一张图看懂Linux内核的“总线-设备-驱动”架构中的设备、驱动函数调用
- 设备、驱动、总线的关系
- 设备,驱动,总线的结构
- linux内核模型---总线,设备,驱动在展讯平台上I2C设备的实例解析
- 总线,设备,驱动的设备模型
- 总线,设备,设备驱动
- 【Linux内核驱动】基于platform总线的miscdevice驱动(LED)
- Linux I2C设备驱动分析 基于2440 2.6.32内核
- 【每周必读一遍】--学习自动化测试 需要潜心修炼内功心法
- java学习网
- C++中的引用
- 用TreeSet生成不重复自动排序随机数组
- struts2中文乱码解决方法 .
- 总线,设备,驱动(基于2.6.30.4内核的)
- CCS3.3卡死问题的解决方法
- JNDI全攻略(一)
- VC++学习日志 MFC基础
- Oracle spatial函数示例
- 系统设计原则
- doc命令
- Php5 ARM 移植
- fedora16如何彻底关闭防火墙???????