现在的位置: 首页 > 综合 > 正文

ok6410学习笔记(14.platform平台总线驱动模型)

2013年04月26日 ⁄ 综合 ⁄ 共 2783字 ⁄ 字号 评论关闭

本节知识点:

基础知识:

1.把最近学的东西串串线,首先学的是kobject,这个东西是在sysfs文件系统中,创建一个目录的基类,在这点上linux有着面向对象的编程思想,也就是什么kset,总线,platform都是继承了kobject的特性,在sys目录中创建目录。

2.学习kobject和kset是为了学习总线设备驱动模型的,因为创建总线,设备,驱动实际就是在/sys/bus目录中创建kobject,其实质也是kobject和kset完成的。
3.platform平台总线驱动模型,其实就是linux内核把,上节那个总线设备驱动模型进行了封装。把本应该自己创建的一条总线,变成了linux替你创建好的一条platform总线而已。
4.这里有一个很迷茫的一点就是,这个platform平台总线驱动模型到底有什么用??我现在的理解是这样的,希望在读了宋宝华的linux设备驱动之后还有体会。
    第一:platform将设备本身的资源注册进入内核,由内核统一管理,在驱动程序使用这些资源的时候使用统一的接口,提高驱动的可移植性。
    第二:这是一个很常用的驱动模型,也叫框架吧,linux设备驱动  叫他是工程中的驱动。
    第三:这模型仅仅是将驱动和设备分开,然后当有新设备或者新驱动的时候,去匹配,匹配成功再调用driver模块中的probe函数,完成具体的驱动程序。也就是说platform仅仅是一个框架,功能驱动在probe函数里面,是字符驱动,还是块驱动啊 都是在probe函数里面完成。

驱动结构及重要函数:

在platform_device里面:
1.在struct platform_device结构体中  填写设备名称,id,设备资源结构,或者通过struct platform_device *platform_device_alloc(const char *name,int id)函数来定义platform_device
2.platform_device_register(&led_dev)注册平台设备进入内核 
在platform_driver里面:
1.在struct platform_driver led_drv={
.probe=led_drv_probe,
.remove=led_drv_remove,
.driver={
.owner=THIS_MODULE,
.name="plat_led",  //platform总线  里面驱动的名字   这个名字要和设备的名字一样
}
};里面定义  驱动名字 ,probe函数等
2.利用platform_driver_register(&led_drv)  注册驱动进入内核
其实国嵌在这里的时候看了内核代码的,有几个结论如下:
1.platform总线,就是内核定义的一条总线,并且将他的设备和驱动进行了封装
2.找到了bus_for_each_dev,  这个函数是总线在不断的轮询总线中的dev设备,然后通过match函数,判断设备和驱动是否匹配
3.platform的match就是比较platform_device.name和platform_driver.driver.name

本节代码:

plat-dev.c:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/platform_device.h>

MODULE_AUTHOR("Hao");
MODULE_LICENSE("Dual BSD/GPL");

struct platform_device led_dev={
	.name="plat_led",  //platform总线  里面设备的名字   这个名字要和驱动的名字一样
	.id=-1,	
};

static int __init platform_led_dev_init(void)
{
		int ret=0;
		ret=platform_device_register(&led_dev);
		if(ret)
		{
				printk("platform_device_register failed!!\n");
		}
		return ret;
}

static void __exit platform_led_dev_exit(void)
{
		platform_device_unregister(&led_dev);
}

module_init(platform_led_dev_init);
module_exit(platform_led_dev_exit);

plat-drv.c:

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/platform_device.h>

MODULE_AUTHOR("Hao");
MODULE_LICENSE("Dual BSD/GPL");


static int led_drv_probe(struct platform_device *dev)   //这里面写功能驱动
{
		printk("Driver found device which my driver can handle!\n");
    return 0;
}

static int led_drv_remove(struct platform_device *dev)
{
		printk("Driver found device unpluged!\n");
    return 0;
}

struct platform_driver led_drv={
		.probe=led_drv_probe,
		.remove=led_drv_remove,
		.driver={
					.owner=THIS_MODULE,
					.name="plat_led",  //platform总线  里面驱动的名字   这个名字要和设备的名字一样
			}
};


static int __init platform_led_drv_int(void)
{
		return platform_driver_register(&led_drv);
}


static void __exit platform_led_drv_exit(void)
{
		platform_driver_unregister(&led_drv);
}


module_init(platform_led_drv_int);
module_exit(platform_led_drv_exit);

抱歉!评论已关闭.