在此之前我们已经完成了自己创建一个总线并且在里面注册了dev和drv
现在我们利用系统已经帮我们创建好的platform总线注册自己的platform_device和platform_driver
这个过程其实和上一章的思路差不多
在dev中我们要用 platform_device_register(&my_dev);注册到总线中
并且实现platform_device结构体的方法
struct platform_device my_dev={
.name="qin_led",//用于匹配的名字
.id=-1,//通常赋值为1
.num_resources=ARRAY_SIZE(led_res),//数据的长度
.resource=led_res,//资源的来源
};
对于资源,其实就是我们要在drv中要取的数据,我们用一个resource结构体来存放
//定义了一个可变数组,
struct resource led_res[]={
[0]={
.start=GPM4CON,//地址的起始值
.end=GPM4CON+SIZE-1,//地址的结束值
.flags=IORESOURCE_MEM,//该资源的类型,这个是内存资源,中断的时候要用IORESOURCE_IRQ中断资源
},
};
在驱动卸载时候要释放内存资源
platform_device_unregister(&my_dev);
这就是我们的platform_device了,接下来是在platform_driver中取出资源
同样是要注册platform_driver_register(&mydrv);
然后实现它的结构体
struct platform_driver mydrv={
.probe=myprobe,
.remove=myremove,
.driver={
.name="qinqin",//如果没有id_table才拿来做匹配
},
.id_table=my_id_table,//优先匹配id_table
};
现在我们来定义id_table
//这是一个可变的数组,可以实现drv对多个dev的匹配
const struct platform_device_id my_id_table[]={
{"qin_led",0x1234},//后面的这个地址可以赋任何值,
{"4412",0x3216},
{"S5pv210",0x7994},//这个驱动可以通过这个可变数组匹配多个设备
};
这样就会优先去匹配id_table中的名字,当名字全部匹配不到才去匹配
.driver={
.name="qinqin",//如果没有id_table才拿来做匹配
},
当匹配成功时候,就会自动调用reprove函数,卸载时候调用remove函数,所以这里的reprove和remove
相当于我们平常的字符的设备驱动中的init入口函数和exit出口函数,我们在里面进行平常的操作就好了
以下代码没有在reprove中实现相应功能,因为太过于简单,只进行注册和匹配
platform_dev.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/device.h>
#include<linux/platform_device.h>
#define gpiobase 0x11000000
#define GPM4CON (gpiobase + 0x02E0)
#define SIZE 24
struct resource led_res[]={
[0]={
.start=GPM4CON,
.end=GPM4CON+SIZE-1,
.flags=IORESOURCE_MEM,
}
};
struct platform_device my_dev={
.name="qin_led",//用于匹配的名字
.id=-1,//通常赋值为1
.num_resources=ARRAY_SIZE(led_res),//数据的长度
.resource=led_res,//资源的来源
};
static int __init mypalte_form_init(void)
{
return platform_device_register(&my_dev);
}
static void __exit mypalte_form_exit(void)
{
platform_device_unregister(&my_dev);
printk("\n\platform_device_unregister!!!!!\n\n");
}
module_init(mypalte_form_init);
module_exit(mypalte_form_exit);
MODULE_LICENSE("GPL");
platform_drv.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/device.h>
#include<linux/platform_device.h>
int myprobe(struct platform_device *pdev){
printk("\n\n myprobe !!!!!!!!!!!\n\n");
}
int myremove(struct platform_device *pdev){
printk("\n\n myremove !!!!!!!!!!!\n\n");
}
const struct platform_device_id my_id_table[]={
{"qin_led",0x1234},//后面的这个地址可以赋任何值,
{"4412",0x3216},
{"S5pv210",0x7994},//这个驱动可以通过这个可变数组匹配多个设备
};
struct platform_driver mydrv={
.probe=myprobe,
.remove=myremove,
.driver={
.name="qinqinq",//如果没有id_table才拿来做匹配
},
.id_table=my_id_table,
};
static int __init mypalte_form_init(void)
{
return platform_driver_register(&mydrv);
}
static void __exit mypalte_form_exit(void)
{
printk("\n\nplatform_driver_unregister!!!!!\n\n");
platform_driver_unregister(&mydrv);
}
module_init(mypalte_form_init);
module_exit(mypalte_form_exit);
MODULE_LICENSE("GPL");
对于drv中获取dev中的资源,有这样的方法