我的内核学习笔记2:platform设备模型

来源:互联网 发布:路由器选择 知乎 编辑:程序博客网 时间:2024/05/18 01:23

说实话,我做这个例子之前,我对linux的platform设备、platform驱动了解不多,只知道有这些东西,但没概念。上网搜索了一些资料,并下了点功夫跟踪了内核源代码,虽然不能说吃透了原理,但也不至于像以前那样一无所知。这篇文章主要是说一下一个简单的驱动例子。

为了明确层次,不把所有代码都放到一个文件中,这个例子中,分别有设备文件simplechar_dev.c,驱动文件simplechar_drv.c以及共用的头文件simplechar.h。为了避免例子十分的简单,额外添加了些结构体,也在代码 中对这些结构体做了测试。总之,可以认为这是一个platform的模板吧。

simplechar.h文件是自定义的结构体:

#ifndef SIMPLECHAR_H#define SIMPLECHAR_Hstruct simplechar_platdata {    char    *name;};#endif

 

simplechar_dev.c文件的代码仅仅与“设备”有关,即定义这个设备有哪些特性(名称、私有数据,等):

/** * @file   simplechar_dev.c * @author Late Lee <latelee@163.com> * @date   Tue Nov 12 21:07:03 2013 *  * @brief   *  *  */#include <linux/kernel.h>#include <linux/init.h>#include <linux/platform_device.h>#include "simplechar.h"// devicestatic struct simplechar_platdata foo_pdata = {    .name        = "gotohell",};// 避免删掉模块时出现警告static void simplechar_dev_release(struct device* dev){    printk(KERN_NOTICE "do %s case of: Device xxx does not have a release() function, it is broken and must be fixed.\n", __func__);    return;}// 另一文件要使用到,此处不能为static// 在/sys/devices/platform/生成目录:simplecharstruct platform_device simplechar_device = {    .name    = "simplechar",    .id      = -1,  // 注:如何为1,则生成目录:simplechar.1    .dev     = {        .platform_data = &foo_pdata,        .release = &simplechar_dev_release,    },};

simplechar_drv.c文件主要实现了“驱动”,驱动的主要代码集中于此:

/** * @file   simplechar_drv.c * @author Late Lee <latelee@163.com> * @date   Tue Nov 12 21:07:15 2013 *  * @brief  platform模型示例 *  * @note   仅用于insmod和rmmod的测试,不具备字符设备特征 *//***/#include <linux/kernel.h>#include <linux/init.h>#include <linux/platform_device.h>#include "simplechar.h"// deviceextern struct platform_device simplechar_device;// our own datastruct simplechar {    int id;    struct simplechar_platdata    *pdata;    char buffer[16];};static inline struct simplechar *pdev_to_owndata(struct platform_device *dev){    return platform_get_drvdata(dev);}static int simplechar_remove(struct platform_device *dev){struct simplechar *foo = pdev_to_owndata(dev);    // 释放自定义数据空间kfree(foo);    return 0;}static int simplechar_test(struct platform_device *dev){    struct simplechar *foo = NULL;        foo = pdev_to_owndata(dev);        printk(KERN_NOTICE "%s: get id: %d data: %s\n", __func__, foo->id, foo->buffer);        return 0;}static int simplechar_probe(struct platform_device *dev){    struct simplechar_platdata *pdata = dev->dev.platform_data;    struct simplechar *foo = NULL;    int ret = 0;    printk(KERN_NOTICE "in %s our data name: %s\n", __func__, pdata->name);    // 申请自定义数据空间    foo = kzalloc(sizeof(struct simplechar), GFP_KERNEL);    if (foo == NULL) {        dev_err(&dev->dev, "No memory for device\n");        return -ENOMEM;    }    // 设置自定义结构体数据    platform_set_drvdata(dev, foo);    foo->id = 250;    strcpy(foo->buffer, "hello world");    // 简单测试    simplechar_test(dev);    return ret;}// driverstatic struct platform_driver simplechar_driver = {    .probe        = simplechar_probe,    .remove        = simplechar_remove,    .driver        = {        .name        = "simplechar",        .owner        = THIS_MODULE,    },};static int __init simplechar_drv_init(void){    int ret = 0;    printk(KERN_NOTICE "in %s\n", __func__);    // 先注册设备(适用于静态定义设备结构体)    ret = platform_device_register(&simplechar_device);    if (ret)    {        printk(KERN_NOTICE "platform_device_register failed!\n");        return ret;    }    // 再注册驱动    ret = platform_driver_register(&simplechar_driver);    if (ret)    {        printk(KERN_NOTICE "platform_driver_register failed!\n");        return ret;    }        printk("%s() ok\n", __func__);        return ret;}static void __exit simplechar_drv_exit(void){    printk(KERN_NOTICE "in %s\n", __func__);    // 先卸载驱动    platform_driver_unregister(&simplechar_driver);    // 再卸载设备    platform_device_unregister(&simplechar_device);}module_init(simplechar_drv_init);module_exit(simplechar_drv_exit);MODULE_AUTHOR("Late Lee");MODULE_DESCRIPTION("Simple platform driver");MODULE_LICENSE("GPL");MODULE_ALIAS("platform:simplechar");

 

原创粉丝点击