Samsung_tiny4412(驱动笔记10)----mdev,bus,device,driver,platform
/***********************************************************************************
*
* mdev,bus,device,driver,platform
*
* 声明:
* 1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会
* 不对齐,从而影响阅读.
* 2. 由于本人水平有限,很难阐述清楚bus device driver platform的关系
* 所以强烈要求您详细参考本次提供的预热文章.
*
*
* 2015-3-21 晴 深圳 尚观 Opt 曾剑锋
**********************************************************************************/ \\\\\\\\\\\--*目录*--//////////
| 一. 预热文章:
| 二. mdev 原理及配置:
| 三. bus device driver接口:
| 四. platform bus接口
\\\\\\\\\\\\\\\//////////////// 一. 预热文章:
. linux设备驱动模型(上):
http://m.blog.csdn.net/blog/zhuzongwei1988/5785461
. [嵌入式Linux学习七步曲之第四篇 Linux内核移植]详解Linux2.6内核中
基于platform机制的驱动模型:
http://blog.csdn.net/sailor_8318/article/details/5267698
. [嵌入式Linux学习七步曲之第五篇 Linux内核移植]PowerPC+Linux2..25平台
下的I2C驱动架构分析:
http://blog.csdn.net/sailor_8318/article/details/5905988
. [嵌入式Linux学习七步曲之第五篇 Linux内核移植]PowerPC+Linux2..25平台
下的SPI驱动架构分析:
http://blog.csdn.net/sailor_8318/article/details/5977733 二. mdev 原理及配置:
. 在/etc/init.d/rcS中最后执行命令:
#采用设备模型进行创建设备节点的必须加上,热插拔处理
echo "/sbin/mdev" > /proc/sys/kernel/hotplug
mdev -s
. mdev扫描/sys/lock(块设备保存在/sys/block目录下,2.6.25版本以后,块设备也保存在
/sys/class/block目录下.mdev扫描/sys/block是为了实现向后兼容和/sys/class两个
目录下的dev属性文件,从该dev属性文件中获取设备编号(dev属性文件以"major:minor\n"
形式保存设备编号),并以包含该dev属性文件的目录名称作为设备名device_name(即包含
dev属性文件的目录为device_name,而/sys/class和/device_name之间的那部分目录称为
subsystem,也就是每个dev属性文件所在的路径都可表示/sys/class/subsystem/device_name/dev),
. 并在/dev目录下创建相应的设备文件.例如:
cat /sys/class/tty/tty0/dev会得到4:,subsystem为tty,device_name为tty0.
. 系统运行起来以后,每次创建新的节点的时候都会调用mdev,并根据/etc/mdev.conf文件
做相应的事,如果配置中没有对应的配置,那就按常规处理:
cat > /etc/mdev.conf << EOF
misc_dev : =test/my_device
event.* : =input/
mice : =input/
mouse0 : =input/
dsp : =sound/
sdb[-] : * /sbin/auto_mount
EOF
配置解析:
. 格式: <device regex> <uid>:<gid> <octal permissins> [<@|$|*> <command>]
. @在创建设备节点后运行命令;
. $在删除设备节点前运行命令;
. *创建设备节点后和创建设干杯节点前都会运行命令;
. =input: 表示将mice放在/dev/input目录下;
. =test/my_device: 表示将misc_dev改名字为my_device,并放在/dev/test目录下;
. 按照上面的操作,可以实现U盘的自动挂载. 三. bus device driver接口:
. 总线注册:
struct bus_type bus;
bus_register(&bus);
. 总线注销:
bus_unregister(&bus);
. 设备注册:
struct device dev;
device_register(&dev);
. 设备注销:
device_unregister(&dev);
. 驱动注册:
struct device_driver drv;
driver_register(&drv);
. 驱动注销:
driver_unregister(&drv);
. bus device接口实例Demo:
...
//总线通过match函数决定总线匹配规则,返回0代表匹配失败
int up_match(struct device *dev, struct device_driver *drv)
{
printk("try to match!\n"); /**
* 通过名字匹配设备和驱动,init_name中的值会赋给kobj.name
* 并且init_name中的值会变成NULL,所以如果要通过名字匹配
* 设备驱动,需要比较的是dev->kobj.name和drv->name的值.
* 如下方式是错误的:
* return !strcmp(dev->init_name, drv->name);
*/
return !strcmp(dev->kobj.name, drv->name);
} struct bus_type up_bus = {
.name = "niubi_bus",
.match = up_match,
};
EXPORT_SYMBOL(up_bus); void test_release(struct device *dev)
{
} struct device up_dev = {
.init_name = "bus_device",
.release = test_release,
};
EXPORT_SYMBOL(up_dev); int __init test_init(void)
{
int ret; ret = bus_register(&up_bus);
if(ret)
{
printk("bus_register FAILED!\n");
goto err0;
} ret = device_register(&up_dev);
if(ret)
{
printk("device_register FAILED!\n");
goto err1;
} return ret; err1:
bus_unregister(&up_bus);
err0:
return ret;
} void __exit test_exit(void)
{
bus_unregister(&up_bus);
}
... . device_driver接口实例Demo:
...
extern struct bus_type up_bus; //dev指向匹配的设备结构
static int up_probe(struct device *dev)
{
printk("Probe.\n"); return ;
} static int up_remove(struct device *dev)
{
printk("Remove.\n"); return ;
} struct device_driver drv = {
.owner = THIS_MODULE,
.name = "niubi_dev", //match的时候要用到
.bus = &up_bus,
.probe = up_probe,
.remove = up_remove,
}; int __init test_init(void)
{
int ret;
ret = driver_register(&drv);
if(ret)
printk("driver_register FAILED!\n"); return ret;
} void __exit test_exit(void)
{
driver_unregister(&drv);
}
... 四. platform bus接口
. 注册平台设备:
struct platform_device pdev;
platform_device_register(&dev);
. 注销平台设备:
platform_device_unregister(&dev);
. 注册平台驱动:
struct platform_driver pdrv;
platform_driver_register(&pdrv);
. 注销平台驱动:
platform_driver_unregister(&pdrv); . platform_device接口Demo: #include <linux/module.h>
#include <linux/platform_device.h> //定义自己的平台数据结构
struct my_platform_data {
int w;
int h;
char name[];
}; struct my_platform_data pdata = {
.w = ,
.h = ,
.name = "lcd_screen",
}; struct resource res[] = {
[] = {
.start = 0x10000000,
.end = 0x10000000 + SZ_128 - ,
.flags = IORESOURCE_MEM,
},
[] = {
.start = 0x20000000,
.end = 0x20000000 + SZ_128 - ,
.flags = IORESOURCE_MEM,
},
[] = {
.start = 0x30,
.end = 0x30,
.flags = IORESOURCE_IRQ,
},
}; void test_release(struct device *dev)
{
} //设备的resource保存在设备结构里
struct platform_device pdev = {
.name = "device_v3",
.id = -,
.dev = {
.release = test_release,
.platform_data = &pdata,
},
.num_resources = ARRAY_SIZE(res),
.resource = res,
}; int __init test_init(void)
{
int ret;
ret = platform_device_register(&pdev);
if(ret)
printk("platform_device_register FAILED!\n"); return ret;
} void __exit test_exit(void)
{
platform_device_unregister(&pdev);
} module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL"); . platform_device接口Demo: #include <linux/module.h>
#include <linux/platform_device.h> //定义自己的平台数据结构
struct my_platform_data {
int w;
int h;
char name[];
}; static int up_probe(struct platform_device *pdev)
{
int i;
struct my_platform_data *pdata = pdev->dev.platform_data; for(i = ; i < pdev->num_resources; i++)
{
printk("start = %x, end = %x\n",
pdev->resource[i].start,
pdev->resource[i].end);
}
printk("==========================\n");
printk("platform data.\n");
printk("width = %d, height = %d\n%s\n",
pdata->w, pdata->h, pdata->name); return ;
} static int up_remove(struct platform_device *pdev)
{
printk("In %s func.\n", __func__); return ;
} //最后一个元素清0
struct platform_device_id up_ids[] = {
{"device_v1", },
{"device_v2", },
{"device_v3", },
{"device_v4", },
{"device_v5", },
{},
}; //使用id_table和设备匹配
struct platform_driver pdrv = {
.probe = up_probe,
.remove = up_remove,
.driver = {
.name = "xxxxxxx",
.owner = THIS_MODULE,
},
.id_table = up_ids,
}; int __init test_init(void)
{
int ret;
ret = platform_driver_register(&pdrv);
if(ret)
printk("platform_driver_register FAILED!\n"); return ret;
} void __exit test_exit(void)
{
platform_driver_unregister(&pdrv);
} module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
Samsung_tiny4412(驱动笔记10)----mdev,bus,device,driver,platform的更多相关文章
- linux下bus,device,driver三者关系
linux下bus,device,driver三者关系 1.bus: 总线作为主机和外设的连接通道,有些总线是比较规范的,形成了很多协议.如 PCI,USB,1394,IIC等.任何设备都可以选择合适 ...
- Samsung_tiny4412(驱动笔记01)----linux 3.5,U-Boot,Busybox,SD卡启动环境搭建
/*********************************************************************************** * * linux 3.5,U ...
- Samsung_tiny4412(驱动笔记04)----volatile,container_of,file_operations,file,inode
/*********************************************************************************** * * volatile,co ...
- Samsung_tiny4412(驱动笔记03)----字符设备驱动基本操作及调用流程
/*********************************************************************************** * * 字符设备驱动基本操作及 ...
- Samsung_tiny4412(驱动笔记09)----alloc_pages,kmalloc,vmalloc,kmem_cache,class
/*********************************************************************************** * * alloc_pages ...
- Samsung_tiny4412(驱动笔记07)----spinlock,semaphore,atomic,mutex,completion,interrupt
/*********************************************************************************** * * spinlock,se ...
- Samsung_tiny4412(驱动笔记06)----list_head,proc file system,GPIO,ioremap
/**************************************************************************** * * list_head,proc fil ...
- Samsung_tiny4412(驱动笔记05)----Makefile,open,read,write,lseek,poll,ioctl,fasync
/*********************************************************************************** * * Makefile,op ...
- 【驱动笔记10】再谈IRP
文章作者:grayfox作者主页:http://nokyo.blogbus.com原始出处:http://www.blogbus.com/nokyo-logs/34010655.html 这一节会对I ...
随机推荐
- python 集合从头部删除元素
num_set = , , , , ]) num_set.pop() print(num_set) num_set.pop() print(num_set)
- Sublime Text 3.1.1 Build 3176 注册码破解
在hosts(C:\Windows\System32\drivers\etc)加入如下内容: 127.0.0.1 www.sublimetext.com127.0.0.1 li ...
- 《剑指offer》第三十九题(数组中出现次数超过一半的数字)
// 面试题39:数组中出现次数超过一半的数字 // 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例 // 如输入一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, ...
- 算法笔记--2-sat
强连通分量的应用,详见<挑战程序设计>P324 例题1:HDU Peaceful Commission 思路:强连通分量分解,看有没有两个同一个国家的代表在一个强连通分量里,如果有,就是N ...
- Java 集合-Collection接口和迭代器的实现
2017-10-30 00:30:48 Collection接口 Collection 层次结构 中的根接口.Collection 表示一组对象,这些对象也称为 collection 的元素.一些 c ...
- LeetCode--226--翻转二叉树
问题描述: 翻转一棵二叉树. 示例: 输入: 4 / \ 2 7 / \ / \ 1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 备注: 这个问题是受到 Max Howel ...
- 20170813pptVBA批量插入图片
Sub AddSldIn() Dim Pre As Presentation Dim NewSld As Slide Set Pre = Application.ActivePresentation ...
- Vue.js Cookbook: 添加实例属性; 👍 axios(4万➕✨)访问API; filters过滤器;
add instance properties //加上$,防止和已经定义的data,method, computed的名字重复,导致被覆写.//可以自定义添加其他符号. Vue.prototype. ...
- Android动画(Animations)
动画类型Android的animation由四种类型组成 XML中 alpha : 渐变透明度动画效果 scale :渐变尺寸伸缩动画效果 translate : 画面转换位置移动动画效果 ro ...
- Ant Man CodeForces - 704B (图论,贪心)
大意: 给N个点,起点S终点T,每个点有X,A,B,C,D,根据I和J的X坐标可得I到J的距离计算公式 |xi - xj| + ci + bj seconds if j< i |xi - xj| ...