一、platform_device 编程
1、驱动程序入口出口函数:
module_init(led_plat_dev_init);
module_exit(led_plat_dev_exit);
MODULE_LICENSE("GPL");
2、编写init和exit框架
staic int __init led_plat_dev_init(void)
{
}
static void __exit led_plat_dev_exit(void)
{
}
3、platform_device结构体成员
struct platform_device
填充platform_device成员:include\linux\platform_device.h
struct platform_device {
const char * name;//名字--用于匹配
int id;// 表示不同的控制器组--一般为-1
struct device dev;//父类
u32 num_resources;//资源的个数
struct resource * resource;//资源
const struct platform_device_id *id_entry;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
//示例:
struct platform_device led_pdev = {
.name = "s5pv210_led",
.id = -1,
.num_resources = ARRAY_SIZE(led_res),
.resource = led_res,
}
4、构建resource结构体
struct resource {
resource_size_t start; //起始位置
resource_size_t end;//结束位置
const char *name;//名字自定义
unsigned long flags;//区分中断资源还是地址资源
struct resource *parent, *sibling, *child;
};
//示例:
struct resource led_res[] = {
[0] = {
.start = LED_PHY_ADDR,
.end = LED_PHY_ADDR_LEN + LED_PHY_ADDR -1,
.name = "GPC0_3_4",
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 888,
.end = 888,
.name = "test_irq",
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = 0x12345678,
.end = 0x12345678 + 4 -1,
.name = "test_mem" ,
.flags = IORESOURCE_MEM ,
},
};
include\linux\platform_device.h
此头文件包含platform device的注册与注销函数:
extern int platform_device_register(struct platform_device *);
extern void platform_device_unregister(struct platform_device *);
//示例:
staic int __init led_plat_dev_init(void)
{
return platform_device_register(&led_pdev);
}
static void __exit led_plat_dev_exit(void)
{
return platform_device_unregister(&led_pdev);
}
二、platform_driver 编程
1、声明驱动入口和出口函数:
module_init(led_plat_drv_init);
module_exit(led_plat_drv_exit);
MODULE_LICENSE("GPL");
2、编写init和exit框架
static int __init led_plat_drv_init(void)
{
}
static void __exit led_plat_drv_exit(void)
{
}
3、platform_driver注册和注销
//示例:
static int __init led_plat_drv_init(void)
{
return platform_driver_register(&led_pdrv);
}
static void __exit led_plat_drv_exit(void)
{
return platform_driver_unregister(&led_pdrv);
}
4、填充struct platform_driver结构体
struct platform_driver {
int (*probe)(struct platform_device *);//匹配成功之后被调用
int (*remove)(struct platform_device *);//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;//列表--用于匹配(优先用于匹配)
}
struct device_driver {
const char *name; //Name of the device driver设备驱动的名字
struct bus_type *bus; //The bus which the device of this driver belongs to此驱动属于哪一个设备总线
struct module *owner; //The module owner 模块所有者
const char *mod_name; /* used for built-in modules 用于编译进模块 */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
const struct of_device_id *of_match_table; //The open firmware table 打开固件表
int (*probe) (struct device *dev); /*Called to query the existence of a specific device whether this driver can work with it, and bind the driver to a specific device.回调与驱动相匹配的指定设备,并绑定驱动到指定设备*/
int (*remove) (struct device *dev); /*Called when the device is removed from the system to unbind a device from this driver*/
void (*shutdown) (struct device *dev); //Called at shut-down time to quiesce the device
int (*suspend) (struct device *dev, pm_message_t state); /* Called to put the device to sleep mode. Usually to a low power state*/
int (*resume) (struct device *dev); //Called to bring a device from sleep mode
const struct attribute_group **groups; //Default attributes that get created by the driver core automatically
const struct dev_pm_ops *pm; //Power management operations of the device which matched this driver
struct driver_private *p; //Driver core's private data, no one other than the driver core can touch this.
}
//示例:
struct platform_driver led_pdrv = {
.probe = led_pdrv_probe,
.remove = led_pdrv_remove,
.driver = {
.name = "Samsung led_drv",
},
.id_table = led_id_table,
}
struct platform_device_id led_id_table[] ={
{"s3c2410_led", 0x22222},
{"s5pv210_led", 0x55555},
{"exynos4412_led", 0x4444},
}
int led_pdrv_probe(struct platform_device *pdev)
{
led_dev = kzalloc(sizeof(struct s5pv210_led), GFP_KERNEL);
led_dev->major = register_chrdev( 0, "plat_led_drv", &led_fops);
led_dev->cls = class_create(THIS_MODULE, "led_cls");
led_dev->dev = device_create(led_dev->cls, NULL,
MKDEV(led_dev->major, 0), NULL, "led0");
led_dev->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
led_dev->reg_virt_base = ioremap(led_dev->mem_res->start, resource_size(led_dev->mem_res));
int irqno = platform_get_irq(pdev, 0);
return 0;
}
int led_pdrv_remove(struct platform_device *pdev)
{
iounmap(led_dev->reg_virt_base);
device_destroy(led_dev->cls,MKDEV(led_dev->major, 0));
class_destroy(led_dev->cls);
unregister_chrdev(led_dev->major, "plat_led_drv");
kfree(led_dev);
return 0;
}
5、编程:struct file_operations 初级驱动操作函数