构建一个platform总线模型

在此之前我们已经完成了自己创建一个总线并且在里面注册了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中的资源,有这样的方法
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值