Samsung_tiny4412(驱动笔记10)—-mdev,bus,device,driver,platform「建议收藏」

Samsung_tiny4412(驱动笔记10)—-mdev,bus,device,driver,platform「建议收藏」|一.预热文章:|二.mdev原理及配置:|三.busdevicedriver接口:|四.platformbus

大家好,又见面了,我是你们的朋友全栈君。

/***********************************************************************************
 *                    
 *                           mdev,bus,device,driver,platform
 *
 *   声明:
 *       1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会
 *          不对齐,从而影响阅读.
 *       2. 由于本人水平有限,很难阐述清楚bus device driver platform的关系
 *          所以强烈要求您详细参考本次提供的预热文章.
 *
 *
 *                                          2015-3-21 晴 深圳 尚观 Opt 曾剑锋
 **********************************************************************************/

                        \\\\\\\\\\\--*目录*--//////////
                        |  一. 预热文章:              
                        |  二. mdev 原理及配置:       
                        |  三. bus device driver接口: 
                        |  四. platform bus接口       
                        \\\\\\\\\\\\\\\////////////////

一. 预热文章:
    1. linux设备驱动模型(上):
        http://m.blog.csdn.net/blog/zhuzongwei1988/5785461
    2. [嵌入式Linux学习七步曲之第四篇 Linux内核移植]详解Linux2.6内核中
        基于platform机制的驱动模型:
        http://blog.csdn.net/sailor_8318/article/details/5267698
    3. [嵌入式Linux学习七步曲之第五篇 Linux内核移植]PowerPC+Linux2.6.25平台
        下的I2C驱动架构分析:
        http://blog.csdn.net/sailor_8318/article/details/5905988
    4. [嵌入式Linux学习七步曲之第五篇 Linux内核移植]PowerPC+Linux2.6.25平台
        下的SPI驱动架构分析:
        http://blog.csdn.net/sailor_8318/article/details/5977733

二. mdev 原理及配置:
    1. 在/etc/init.d/rcS中最后执行命令:
        #采用设备模型进行创建设备节点的必须加上,热插拔处理
        echo "/sbin/mdev" > /proc/sys/kernel/hotplug
        mdev -s
    2. mdev扫描/sys/lock(块设备保存在/sys/block目录下,2.6.25版本以后,块设备也保存在
        /sys/class/block目录下.mdev扫描/sys/block是为了实现向后兼容和/sys/class两个
        目录下的dev属性文件,从该dev属性文件中获取设备编号(dev属性文件以"major:minor\n"
        形式保存设备编号),并以包含该dev属性文件的目录名称作为设备名device_name(即包含
        dev属性文件的目录为device_name,而/sys/class和/device_name之间的那部分目录称为
        subsystem,也就是每个dev属性文件所在的路径都可表示/sys/class/subsystem/device_name/dev),
    3. 并在/dev目录下创建相应的设备文件.例如:
        cat /sys/class/tty/tty0/dev会得到4:0,subsystem为tty,device_name为tty0.
    4. 系统运行起来以后,每次创建新的节点的时候都会调用mdev,并根据/etc/mdev.conf文件
        做相应的事,如果配置中没有对应的配置,那就按常规处理:
        cat > /etc/mdev.conf << EOF
        misc_dev            0:0     0600    =test/my_device
        event.*             0:0     0600    =input/
        mice                0:0     0600    =input/
        mouse0              0:0     0600    =input/
        dsp                 0:0     0600    =sound/
        sdb[0-9]            0:0     0644    * /sbin/auto_mount
        EOF
        配置解析:
        1. 格式: <device regex> <uid>:<gid> <octal permissins> [<@|$|*> <command>]
            1. @在创建设备节点后运行命令;
            2. $在删除设备节点前运行命令;
            3. *创建设备节点后和创建设干杯节点前都会运行命令;
        2. =input: 表示将mice放在/dev/input目录下;
        3. =test/my_device: 表示将misc_dev改名字为my_device,并放在/dev/test目录下;
    5. 按照上面的操作,可以实现U盘的自动挂载.

三. bus device driver接口:
    1. 总线注册:
        struct bus_type bus;
        bus_register(&bus);
    2. 总线注销:
        bus_unregister(&bus);
    3. 设备注册:
        struct device dev;
        device_register(&dev);
    4. 设备注销:
        device_unregister(&dev);
    5. 驱动注册:
        struct device_driver drv;
        driver_register(&drv);
    6. 驱动注销:
        driver_unregister(&drv);
    7. bus device接口实例Demo:
        ...
        //总线通过match函数决定总线匹配规则,返回0代表匹配失败
        int up_match(struct device *dev, struct device_driver *drv)
        {
            printk("try to match!\n");
        
            /** 
             * 通过名字匹配设备和驱动,init_name中的值会赋给kobj.name
             * 并且init_name中的值会变成NULL,所以如果要通过名字匹配
             * 设备驱动,需要比较的是dev->kobj.name和drv->name的值.
             * 如下方式是错误的:
             *     return !strcmp(dev->init_name, drv->name);
             */
            return !strcmp(dev->kobj.name, drv->name);
        }
        
        struct bus_type up_bus = {
            .name   = "niubi_bus",
            .match  = up_match,
        };
        EXPORT_SYMBOL(up_bus);
        
        void test_release(struct device *dev)
        {
        }
        
        struct device up_dev = {
            .init_name  = "bus_device",
            .release    = test_release,
        };
        EXPORT_SYMBOL(up_dev);
        
        int __init test_init(void)
        {
            int ret;
        
            ret = bus_register(&up_bus);
            if(ret)
            {
                printk("bus_register FAILED!\n");
                goto err0;
            }
        
            ret = device_register(&up_dev);
            if(ret)
            {
                printk("device_register FAILED!\n");
                goto err1;
            }
        
            return ret;
        
        err1:
            bus_unregister(&up_bus);
        err0:
            return ret;
        }
        
        void __exit test_exit(void)
        {
            bus_unregister(&up_bus);
        }
        ...
    
    8. device_driver接口实例Demo:
        ...
        extern struct bus_type up_bus;
        
        //dev指向匹配的设备结构
        static int up_probe(struct device *dev)
        {
            printk("Probe.\n");
        
            return 0;
        }
        
        static int up_remove(struct device *dev)
        {
            printk("Remove.\n");
        
            return 0;
        }
        
        struct device_driver drv = {
            .owner  = THIS_MODULE,
            .name   = "niubi_dev", //match的时候要用到
            .bus    = &up_bus,
            .probe  = up_probe,
            .remove = up_remove,
        };
        
        int __init test_init(void)
        {
            int ret;
            ret = driver_register(&drv);
            if(ret)
                printk("driver_register FAILED!\n");
        
            return ret;
        }
        
        void __exit test_exit(void)
        {
            driver_unregister(&drv);
        }
        ...

四. platform bus接口
    1. 注册平台设备:
        struct platform_device pdev;
        platform_device_register(&dev);
    2. 注销平台设备:
        platform_device_unregister(&dev);
    3. 注册平台驱动:
        struct platform_driver pdrv;
        platform_driver_register(&pdrv);
    4. 注销平台驱动:
        platform_driver_unregister(&pdrv);

    5. platform_device接口Demo:

        #include <linux/module.h>
        #include <linux/platform_device.h>
        
        //定义自己的平台数据结构
        struct my_platform_data {
            int w;
            int h;
            char name[20];
        };
        
        struct my_platform_data pdata = {
            .w      = 800,
            .h      = 480,
            .name   = "lcd_screen",
        };
        
        struct resource res[] = {
            [0] = {
                .start  = 0x10000000,
                .end    = 0x10000000 + SZ_128 - 1,
                .flags  = IORESOURCE_MEM,
            },
            [1] = {
                .start  = 0x20000000,
                .end    = 0x20000000 + SZ_128 - 1,
                .flags  = IORESOURCE_MEM,
            },
            [2] = {
                .start  = 0x30,
                .end    = 0x30,
                .flags  = IORESOURCE_IRQ,
            },
        };
        
        void test_release(struct device *dev)
        {
        }
        
        //设备的resource保存在设备结构里
        struct platform_device pdev = {
            .name   = "device_v3",
            .id     = -1,
            .dev    = {
                .release        = test_release,
                .platform_data  = &pdata,
            },
            .num_resources  = ARRAY_SIZE(res),
            .resource       = res,
        };
        
        int __init test_init(void)
        {
            int ret;
            ret = platform_device_register(&pdev);
            if(ret)
                printk("platform_device_register FAILED!\n");
        
            return ret;
        }
        
        void __exit test_exit(void)
        {
            platform_device_unregister(&pdev);
        }
        
        module_init(test_init);
        module_exit(test_exit);
        MODULE_LICENSE("GPL");

    6. platform_device接口Demo:

        #include <linux/module.h>
        #include <linux/platform_device.h>
        
        //定义自己的平台数据结构
        struct my_platform_data {
            int w;
            int h;
            char name[20];
        };
        
        static int up_probe(struct platform_device *pdev)
        {
            int i;
            struct my_platform_data *pdata = pdev->dev.platform_data;
        
            for(i = 0; i < pdev->num_resources; i++)
            {
                printk("start = %x, end = %x\n",
                       pdev->resource[i].start,
                       pdev->resource[i].end);
            }
            printk("==========================\n");
            printk("platform data.\n");
            printk("width = %d, height = %d\n%s\n",
                    pdata->w, pdata->h, pdata->name);
        
            return 0;
        }
        
        static int up_remove(struct platform_device *pdev)
        {
            printk("In %s func.\n", __func__);
        
            return 0;
        }
        
        //最后一个元素清0
        struct platform_device_id up_ids[] = {
            {"device_v1", 1},
            {"device_v2", 2},
            {"device_v3", 3},
            {"device_v4", 4},
            {"device_v5", 5},
            {},
        };
        
        //使用id_table和设备匹配
        struct platform_driver pdrv = {
            .probe  = up_probe,
            .remove = up_remove,
            .driver = {
                .name   = "xxxxxxx",
                .owner  = THIS_MODULE,
            },
            .id_table = up_ids,
        };
        
        int __init test_init(void)
        {
            int ret;
            ret = platform_driver_register(&pdrv);
            if(ret)
                printk("platform_driver_register FAILED!\n");
        
            return ret;
        }
        
        void __exit test_exit(void)
        {
            platform_driver_unregister(&pdrv);
        }
        
        module_init(test_init);
        module_exit(test_exit);
        MODULE_LICENSE("GPL");

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/154532.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 机器学习之支持向量回归(SVR)

    机器学习之支持向量回归(SVR)简介支持向量机(SupportVectorMachine)是由Vapnik等人于1995年提出来的,之后随着统计理论的发展,支持向量机SVM也逐渐受到了各领域研究者的关注,在很短的时间就得到了很广泛的应用。支持向量机是被公认的比较优秀的分类模型。同时,在支持向量机的发展过程中,其理论方面的研究得到了同步的发展,为支持向量机的研究提供了强有力的理论支撑。本实训项目主要围绕支持向量机的原理和技术进行介绍,并基于实际案例进行实战实训。线性支持向量机#encoding=utf8fromsk

  • mysql是mpp数据库_mysql迁移mpp数据库Greenplum[通俗易懂]

    mysql是mpp数据库_mysql迁移mpp数据库Greenplum[通俗易懂]1.场景描述因兄弟项目中mysql有点扛不住了,要做sql优化,但是业务有点小复杂,优化起来有点麻烦(sql嵌套有点多),便想着用Mpp数据库Greenplum测试下,看性能和复杂度怎么样,趟趟水。2.解决方案初步的想法是:因为mysql和postgresql(Greenplum建立在postgresql之上,i’m软件老王)都是使用的标准sql,直接把mysql的建表语句在Greenplum…

    2022年10月31日
  • 什么叫做信令_核心网与普通网

    什么叫做信令_核心网与普通网[导读] 本文为你介绍信令与信令网的含义、结构、信令方式,信令网的划分、性能指标、编码方式、信令的三层结构等。关键词:信令网信令什么是信令?信令是终端和终端、终端和网络之间传递的一种消

  • 随机数生成机制

    随机数生成机制

  • 香农编码的 matlab 实现「建议收藏」

    香农编码的 matlab 实现「建议收藏」closeall;clearall;clc;%香农编码matlab实现p=[0.50.190.190.070.05]%输入概率n=length(p);y=fliplr(sort(p));D=zeros(n,4);D(:,1)=y’;fori=2:nD(1,2)=0;D(i,2)=D(i-1,1)+D(i-1,2)…

  • origin画图数据_origin多元线性回归拟合

    origin画图数据_origin多元线性回归拟合制图完成效果图如下。1.原始数据为真实值与预测值。2.另外两列是制作中间的标准线。优化直线。3.4.对预测值与真实值的图进行优化。5.将标准线图层复制到当前页面,ctrl+C,V就行了。将标准线的网格删除。将线移动到该有的位置即可。对周围的字体大小等修正后即可。…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号