• 嵌入式Linux应用开发-第十二章设备树的改造


    第十二章 LED模板驱动程序的改造:设备树

    在这里插入图片描述

    12.1 总结3种写驱动程序的方法

    在这里插入图片描述

    核心永远是 file_operations结构体
    上述三种方法,只是指定“硬件资源”的方式不一样。

    从上图可以知道,platform_device/platform_driver只是编程的技巧,不涉及驱动的核心。

    12.2 怎么使用设备树写驱动程序

    12.2.1 设备树节点要与platform_driver能匹配

    在我们的工作中,驱动要求设备树节点提供什么,我们就得按这要求去编写设备树。
    但是,匹配过程所要求的东西是固定的:
    ① 设备树要有 compatible属性,它的值是一个字符串
    ② platform_driver中要有 of_match_table,其中一项的.compatible成员设置为一个字符串 ③ 上述 2个字符串要一致。
    示例如下:
    在这里插入图片描述

    12.2.2 设备树节点指定资源,platform_driver获得资源

    如果在设备树节点里使用 reg属性,那么内核生成对应的 platform_device时会用 reg属性来设置IORESOURCE_MEM类型的资源。
    如果在设备树节点里使用 interrupts属性,那么内核生成对应的 platform_device时会用 reg属性来设置 IORESOURCE_IRQ类型的资源。对于 interrupts属性,内核会检查它的有效性,所以不建议在设备树里使用该属性来表示其他资源。
    在我们的工作中,驱动要求设备树节点提供什么,我们就得按这要求去编写设备树。驱动程序中根据pin属性来确定引脚,那么我们就在设备树节点中添加 pin属性。
    设备树节点中:

    #define GROUP_PIN(g,p) ((g<<16) | (p)) 
    xxxxxx_led0 { 
       compatible = “xxxxxx,led”; 
       pin = <GROUP_PIN(5, 3)>; 
    }; 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    驱动程序中,可以从 platform_device中得到 device_node,再用 of_property_read_u32得到属性的值:

    struct  device_node* np = pdev->dev. of_node; 
    int led_pin; 
    int err = of_property_read_u32(np, “pin”, &led_pin); 
    
    • 1
    • 2
    • 3

    12.3 开始编程

    12.3.1 修改设备树添加led设备节点

    在本实验中,需要添加的设备节点代码是一样的,你需要找到你的单板所用的设备树文件,在它的根节点下添加如下内容:

    #define GROUP_PIN(g,p) ((g<<16) | (p)) 
    xxxxxx_led@0 { 
     compatible = "xxxxxx,leddrv"; 
     pin = <GROUP_PIN(3, 1)>; 
    }; 
    xxxxxx_led@1 { 
     compatible = "xxxxxx,leddrv"; 
     pin = <GROUP_PIN(5, 8)>; 
    }; 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    12.3.1.1 对于 xxxxxx-am335x 单板

    设备树文件是:内核源码目录中 arch/arm/boot/dts/xxxxxx-am335x.dts
    修改、编译后得到 arch/arm/boot/dts/xxxxxx-am335x.dtb文件。
    要更换板子上的设备树文件,启动板子后,更换这个文件:/boot/xxxxxx-am335x.dtb

    12.3.1.2 对于 firefly-rk3288

    设备树文件是:内核源码目录中 arch/arm/boot/dts/rk3288-firefly.dts
    修改、编译后得到 arch/arm/boot/dts/rk3288-firefly.dtb文件。
    对于这款板子,本教程中我们使用 SD卡上的系统。
    要更换板上的设备树文件,你可以使用 SD卡启动开发板后,更换这个文件:/boot/rk3288-firefly.dtb

    12.3.1.3 对于 firefly的 roc-rk3399-pc

    设备树文件是:内核源码目录中 arch/arm64/boot/dts/rk3399-roc-pc.dts
    修改、编译后得到 arch/arm64/boot/dts/rk3399-roc-pc.dtb文件。
    对于这款板子,本教程中我们使用 SD卡上的系统。
    要更换板上的设备树文件,你可以使用 SD卡启动开发板后,更换这个文件:/boot/ rk3399-roc-pc.dtb

    12.3.1.4 对于百问网使用 QEMU模拟的 IMX6ULL板子

    设备树文件是:内核源码目录中 arch/arm/boot/dts/xxxxxx_imx6ul_qemu.dts
    修改、编译后得到 arch/arm/boot/dts/xxxxxx_imx6ul_qemu.dtb文件。

    它是执行 qemu时直接在命令行中指定设备树文件的,你可以打开脚本文件 qemu-imx6ul-gui.sh找到dtb文件的位置,然后使用新编译出来的 dtb去覆盖老文件。

    12.3.1.5 对于野火 imx6ull-pro

    设备树文件是:内核源码目录中 arch/arm/boot/dts/imx6ull-14x14-ebf.dts
    修改、编译后得到 arch/arm/boot/dts/imx6ull-14x14-ebf.dtb文件。
    对于这款板子,本教程中我们使用 SD卡上的系统。
    要更换板上的设备树文件,你可以使用 SD卡启动开发板后,更换这个文件:/boot/imx6ull-14x14-ebf.dtb

    12.3.1.6 对于正点原子 imx6ull-alpha

    设备树文件是:内核源码目录中 arch/arm/boot/dts/imx6ull-14x14-alpha.dts
    修改、编译后得到 arch/arm/boot/dts/imx6ull-14x14-alpha.dtb文件。
    对于这款板子,本教程中我们使用 SD卡上的系统。
    要更换板上的设备树文件,你可以使用 SD卡启动开发板后,更换这个文件:
    /boot/arch/arm/boot/dts/imx6ull-14x14-alpha.dtb

    12.3.2 修改platform_driver的源码

    使用 GIT下载所有源码后,本节源码位于如下目录:

    01_all_series_quickstart\ 
    05_嵌入式 Linux驱动开发基础知识\source\ 
    02_led_drv\05_led_drv_template_device_tree 
    
    • 1
    • 2
    • 3

    关键代码在 chip_demo_gpio.c,主要看里面的 platform_driver,代码如下。
    第 166行指定了 of_match_table,它是用来跟设备树节点匹配的,如果设备树节点中有 compatile属性,并且其值等于第 157行的“xxxxxx,leddrv”,就会导致第 162行的 probe函数被调用。

    156 static const struct of_device_id xxxxxx_leds[] = { 
    157     { .compatible = "xxxxxx,leddrv" }, 
    158     { }, 
    159 }; 
    160 
    161 static struct platform_driver chip_demo_gpio_driver = { 
    162     .probe      = chip_demo_gpio_probe, 
    163     .remove     = chip_demo_gpio_remove, 
    164     .driver     = { 
    165         .name   = "xxxxxx_led", 
    166         .of_match_table = xxxxxx_leds, 
    167     }, 
    168 }; 
    169 
    170 static int __init chip_demo_gpio_drv_init(void) 
    171 { 
    172     int err; 
    173 
    174     err = platform_driver_register(&chip_demo_gpio_driver); 
    175     register_led_operations(&board_demo_led_opr); 
    176 
    177     return 0; 
    178 } 
    179 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    12.4 上机实验

    1.使用新的设备树 dtb文件启动单板,查看/sys/firmware/devicetree/base下有无节点
    2. 查看/sys/devices/platform目录下有无对应的 platform_device 3. 加载驱动:

    # insmod  leddrv.ko 
    # insmod  chip_demo_gpio.ko 
    
    • 1
    • 2
    1. 测试驱动:
    # ./ledtest   /dev/xxxxxx_led0  on # ./ledtest   /dev/xxxxxx_led0  off 
    
    • 1

    12.5 调试技巧

    /sys目录下有很多内核、驱动的信息:

    12.5.1 设备树的信息

    以下目录对应设备树的根节点,可以从此进去找到自己定义的节点。 cd /sys/firmware/devicetree/base/
    节点是目录,属性是文件。
    属性值是字符串时,用 cat命令可以打印出来;属性值是数值时,用 hexdump命令可以打印出来。

    12.5.2 platform_device的信息

    以下目录含有注册进内核的所有 platform_device:

    /sys/devices/platform 
    
    • 1

    一个设备对应一个目录,进入某个目录后,如果它有“driver”子目录,就表示这个 platform_device跟某个 platform_driver配对了。
    比如下面的结果中,平台设备“ff8a0000.i2s”已经跟平台驱动“rockchip-i2s”配对了:

    /sys/devices/platform/ff8a0000.i2s]# ls driver -ld 
    lrwxrwxrwx    1 root     root             0 Jan 18 16:28 driver -> ../../../bus/platform/drivers/rockchip-i2s 
    
    • 1
    • 2

    12.5.3 platform_driver的信息

    以下目录含有注册进内核的所有 platform_driver:

    /sys/bus/platform/drivers 
    
    • 1

    一个 driver对应一个目录,进入某个目录后,如果它有配对的设备,可以直接看到。
    比如下面的结果中,平台驱动“rockchip-i2s”跟 2个平台设备“平台设备“ff890000.i2s”、
    “ff8a0000.i2s”配对了:
    在这里插入图片描述

    注意:一个平台设备只能配对一个平台驱动,一个平台驱动可以配对多个平台设备。

    12.6 课后作业

    请仿照本节提供的程序(位于 05_led_drv_template_device_tree目录),改造你所用的单板的 LED驱动程序。

  • 相关阅读:
    CSS之margin塌陷
    Linux基础教程:5、shell入门前的准备
    [C语言数据结构]队列
    一文搞懂mysql索引底层逻辑,干货满满!
    vue面试题总结
    C++(适配器):stack和queue的底层实现,以及优先级队列和仿函数
    缓存设计的创新之旅:架构的灵魂之一
    AD9361手册解读
    激光SLAM多层料箱机器人HEGERLS A42M SLAM|灵活匹配多种作业高度|支持多尺寸纸箱/料箱混合拣选
    【面试】测试/测开(未完成版)
  • 原文地址:https://blog.csdn.net/kingpower2018/article/details/133361953