platform总线
platform 驱动与传统的设备驱动模型相比,优势在于 platform 机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序使用这些资源时使用统一的接口,这样提高了程序的可移植性。
platform驱动的设计流程
- platform_device 定义
- platform_device 注册
- platform_driver 定义
- platform_driver 注册
平台设备描述
平台设备使用 platform_device 来描述:
struct platform_device
{
const char *name; //设备名
int id; //设备号,配合设备名使用
struct device dev;
u32 num_resources;
struct resources *resources; //设备资源 (重要)
};
平台设备分配:
struct platform_device *platform_device_alloc(const char *name,int id)
参数:
- name:设备名
- id:设备id,一般为-1
平台设备注册
int platform_device_add(struct platform_device *pdev)
平台设备资源
平台设备资源位于设备描述结构体中:
struct resource
{
resource_size_t start; //资源起始物理地址
resource_size_t end; //资源结束物理地址
const char *name; //资源名称
unsigned long flags; //资源的类型,比如 MEM,IO,IRQ类型
struct resource *parent,*sibling,*child;//资源链表指针
};
获取资源
struct resource *platform_get_resource(struct platform_device *dev,unsigned int type,unsigned int num)
参数 :
- dev: 资源所属资源
- type:获取资源类型
- num:获取的资源数
举例:获取中断号:platform_get_resource(pdev,IORESOURCE_IRQ,0)
平台驱动描述
平台驱动注册
平台驱动注册使用函数:
int platform_driver_register(struct platform_driver *)
platform代码展示
device.c
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
MODULE_AUTHOR("zhangbin");
MODULE_LICENSE("GPL");
static struct platform_device *my_device;
static int __init my_device_init(void)
{
int ret = 0;
//分配结构
my_device = platform_device_alloc("my_dev",-1);
//注册设备
ret = platform_device_add(my_device);
if(ret)
platform_device_put(my_device);
return ret;
}
static void my_device_exit()
{
platform_device_unregister(my_device);
}
module_init(my_device_init);
module_exit(my_device_exit);
driver.c
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
MODULE_AUTHOR("zhangbin");
MODULE_LICENSE("GPL");
static int my_probe(struct device *dev)
{
printk("Driver found device which my driver can handle\n");
return 0;
}
static int my_remove(struct device *dev)
{
printk("Driver found device unpluged!\n");
return 0;
}
static struct platform_driver my_driver =
{
.probe = my_probe,
.remove = my_remove,
.driver =
{
.owner = THIS_MODULE,
.name = "my_dev",
}
};
static int __init my_driver_init(void)
{
//注册平台驱动
return platform_driver_register(&my_driver);
}
static void my_driver_exit()
{
platform_driver_unregister(&my_driver);
}
module_init(my_driver_init);
module_exit(my_driver_exit);
Makefile
ifneq ($(KERNELRELEASE),)
obj-m := driver.o #可以修改这里对应不同的文件
else
KDIR := /home/zhangbin/mini6410/linux-2.6.38
all:
make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.c *.symvers
endif