在2.6的内核中很多驱动程序都采用platform形式的驱动程序
platform是一种虚拟总线。platform机制的本身实现并不复杂,由两部分组成:
platform_device和platform_driver
platform_bus内核已经实现好了,只需要基于这条总线进行操作就可以了
1.工作流程
1.定义platform_device
2.注册platform_device
3.定义platform_driver
4.注册platform_driver
1.平台使用 struct platform_device来描述
关键属性
const char *name;//设备名称
int id;//设备编号,配合设备名进行使用
struct resource *resource;//设备资源信息,包括基地址、中断号等
分配使用:
struct platform_device *platform_device_alloc(const char*name,int id)
name:设备名称 id:设备id,一般为-1
2.平台设备注册
使用函数
int platform_device_add(struct platform_device *pdev )
3.设备资源
struct resource{
资源起始物理地址
资源结束物理地址
资源的名称
资源的类型,flags.比如MEM,IO,IRQ类型等
资源链表指针
}
设备的寄存器
static struct resource s3c_wdt_resource1={
.start = 0x44100000,
.end = 0x44200000,
.flags = IORESOURCE_MEM
} 寄存器地址
获取资源
struct resource * platform_get_resource(struct platform_device *dev,unsigned int type,unsigned int num)
dev:资源所属设备
type:获取的资源类型
num:获取的资源数
eg:platform_get_resource(pdev,IORESOURCE_IRQ,0)//获取中断号
4.通过上面所有知识平台设备的定义和注册没有问题
5.平台驱动
通过struct platform_driver来描述
关键数据
probe
6.平台驱动注册
platform_driver_register
原理分析(怎么掉用match 和probe)
1.初始化 platform_driver
2.driver_register驱动注册,->bus_add_driver
->kobjct操作(在相应的sysfs中添加项目 )
->driver_attach->bus_for_each_dev(对每一个设备都调用__driver_attach)
__driver_attach->match(调用总线的match函数)->匹配成功->driver_probe_device->really_probe(先调用总线的probe若没有掉驱动的probe)
平台总线platform的match是通过名称进行匹配的
static struct platform_driver my_driver={
.probe=my_probe,
.remove=my_remove,
.driver={
.owner=THIS_MODULE,
.name="my_dev",
}
}
实际例子:
s3c2410_wdt.c(看门狗驱动程序)
request_mem_region()io_remap() 将物理地址转换为虚拟地址
platform的主要作用是将设备和驱动关联起来
platform是一种虚拟总线。platform机制的本身实现并不复杂,由两部分组成:
platform_device和platform_driver
platform_bus内核已经实现好了,只需要基于这条总线进行操作就可以了
1.工作流程
1.定义platform_device
2.注册platform_device
3.定义platform_driver
4.注册platform_driver
1.平台使用 struct platform_device来描述
关键属性
const char *name;//设备名称
int id;//设备编号,配合设备名进行使用
struct resource *resource;//设备资源信息,包括基地址、中断号等
分配使用:
struct platform_device *platform_device_alloc(const char*name,int id)
name:设备名称 id:设备id,一般为-1
2.平台设备注册
使用函数
int platform_device_add(struct platform_device *pdev )
3.设备资源
struct resource{
资源起始物理地址
资源结束物理地址
资源的名称
资源的类型,flags.比如MEM,IO,IRQ类型等
资源链表指针
}
设备的寄存器
static struct resource s3c_wdt_resource1={
.start = 0x44100000,
.end = 0x44200000,
.flags = IORESOURCE_MEM
} 寄存器地址
获取资源
struct resource * platform_get_resource(struct platform_device *dev,unsigned int type,unsigned int num)
dev:资源所属设备
type:获取的资源类型
num:获取的资源数
eg:platform_get_resource(pdev,IORESOURCE_IRQ,0)//获取中断号
4.通过上面所有知识平台设备的定义和注册没有问题
5.平台驱动
通过struct platform_driver来描述
关键数据
probe
6.平台驱动注册
platform_driver_register
原理分析(怎么掉用match 和probe)
1.初始化 platform_driver
2.driver_register驱动注册,->bus_add_driver
->kobjct操作(在相应的sysfs中添加项目 )
->driver_attach->bus_for_each_dev(对每一个设备都调用__driver_attach)
__driver_attach->match(调用总线的match函数)->匹配成功->driver_probe_device->really_probe(先调用总线的probe若没有掉驱动的probe)
平台总线platform的match是通过名称进行匹配的
static struct platform_driver my_driver={
.probe=my_probe,
.remove=my_remove,
.driver={
.owner=THIS_MODULE,
.name="my_dev",
}
}
实际例子:
s3c2410_wdt.c(看门狗驱动程序)
request_mem_region()io_remap() 将物理地址转换为虚拟地址
platform的主要作用是将设备和驱动关联起来