device
1出处和定义:
<include/linux/platform_device.h>
struct platform_device {
const char *name;
int id;
struct device dev;
u32 num_resources;
struct resource *resource;
....
};
<include/linux/device.h>
struct device {
void *platform_data; //平台特有数据,因具体设备不同而不同,用于设备私有属性的拓展
struct device_node *of_node; //设备树上的节点
void (*release)(struct device *dev);//释放函数
...
};
2.注册:
int platform_device_register(struct platform_device *);
3.卸载:
int platform_device_unregister(struct platform_device *);
工程实例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/current.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include "../private.h"
static struct privatedata priv = {
.val = 0x12345678,
.str = "hello world",
};
struct resource res[] = {
[0] = {
.start = 0x10000000,
.end = 0x20000000-1,
.flags = IORESOURCE_MEM
},
[1] = DEFINE_RES_MEM(0x20000000, 1024),
[2] = {
.start = 10,
.flags = IORESOURCE_IRQ
},
[3] = DEFINE_RES_IRQ(11),
};
static void dev_release(struct device *dev)
{
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
}
static struct platform_device demoobj = {
.name = "demo0",
.id = 0,
.dev = {
.platform_data = &priv,
.release = dev_release,
},
.num_resources = ARRAY_SIZE(res),
.resource = res,
};
#if 0
static int __init device_init(void)
{
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
return platform_device_register(&demoobj);
}
static void __exit device_exit(void)
{
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
platform_device_unregister(&demoobj);
}
module_init(device_init);
module_exit(device_exit);
#else
module_platform_device(demoobj);
#endif
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xxg");
MODULE_DESCRIPTION("Demo for kernel module");
driver
1.定义与出处
<include/linux/platform_device.h>
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
bool prevent_deferred_probe;
};
struct device_driver {
const char *name; //设备名,若一个驱动只对应一个设备则通过该域来匹配
struct driver_private *p; //驱动私有数据
const struct of_device_id *of_match_table;//用于匹配设备树中的设备的ID表
...
};
<include/linux/mod_devicetable.h>
struct of_device_id {
char name[32];
char type[32];
char compatible[128];
const void *data;
};
2.设备匹配表申明:
/*
* 功能:
* 类型: of:设备树写的设备信息 platform (i2c):C语言写的设备信息
*/
MODULE_DEVICE_TABLE(类型,id表)
3.注册:
/*
* 功能:1.将驱动添加到内核的驱动列表中
* 2.匹配设备列表,若匹配成功则回调设备的探测函数
* 输入参数:struct platform_driver:驱动句柄
* 返回值:成功:0 失败:负数
*/
int platform_driver_register(struct platform_driver *);
4.注销:
/*
* 功能:1.将驱动从驱动列表中删除
* 2.回调设备的卸载函数
* 输入参数:struct platform_driver:驱动句柄
* 返回值:none
*/
void platform_driver_unregister(struct platform_driver *);
工程实例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/current.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include "../private.h"
static int demo_probe(struct platform_device *pdev)
{
printk(KERN_INFO "%s : %s : %d - entry.\n", __FILE__, __func__, __LINE__);
return 0;
}
static int demo_remove(struct platform_device *pdev)
{
printk(KERN_INFO "%s : %s : %d - leave.\n", __FILE__, __func__, __LINE__);
return 0;
}
static struct platform_device_id tbl[] = {
{"demo0"},
{"demo1"},
{},
};
MODULE_DEVICE_TABLE(platform, tbl);
static struct platform_driver drv = {
.probe = demo_probe,
.remove = demo_remove,
.driver = {
.name = "demo",
},
.id_table = tbl,
};
#if 1
static int __init drv_init(void)
{
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - entry.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
return platform_driver_register(&drv);
}
static void __exit drv_exit(void)
{
printk(KERN_INFO "(%s:pid=%d), %s : %s : %d - leave.\n",
current->comm, current->pid, __FILE__, __func__, __LINE__);
platform_driver_unregister(&drv);
}
module_init(drv_init);
module_exit(drv_exit);
#else
module_platform_driver(drv);
#endif
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Farsight");
MODULE_DESCRIPTION("Demo for kernel module");