• 设备树(Device Tree)


    设备树介绍:

    设备树是一个描述设备硬件资源的文件,该文件是由节点组成的树形结构。如下:

    / {

    node1 {

    a-string-property = "A string";

    a-string-list-property = "first string", "second string";

    // hex is implied in byte arrays. no '0x' prefix is required

    a-byte-data-property = [01 23 34 56];

    child-node1 {

    first-child-property;

    second-child-property = <1>;

    a-string-property = "Hello, world";

    };

    child-node2 {

    };

    };

    node2 {

    an-empty-property;

    a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */

    child-node1 {

    };

    };

    };

    ① “/”是根节点,node1和node2,是其子节点;

    ② “child-node1” 和 “child-node2”,是node1的子节点;

    ③ a-string-property,是字符串属性;

    ④ a-string-list-property,字符串列表属性;

    ⑤ a-byte-data-property,是字节数据属性;

    节点与属性:

    节点的定义:

    [label:][@unit-address] {

    properties;

    child-node {

    [...]

    };

    };

    常见属性:

    compatible,用来匹配驱动,一般有"供应商,产品"

    #address-cells,决定子节点reg属性的地址cell数,cell是u32

    #size-cells,决定子节点reg属性的地址长度cell数,cell是u32

    reg,一般为设备寄存器地址及范围,如

    设备树实例:

    添加LED节点:

    $ vim arch/arm/boot/dts/exynos4412-fs4412.dts

    fs4412-led {

    compatible = "farsight,fs4412-led";

    reg = <0x114001E0 0x8>;

    };

    $ cd ../../../..

    $ make dtbs

    $ cp arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot

    代码:

    1 #include

    2 #include

    3 #include

    4 #include

    5 #include

    6

    7 #define GPF3CON 0x0

    8 #define GPF3DAT 0x4

    9

    10

    11 void __iomem *led_va;

    12 int led_probe(struct platform_device *pdev)

    13 {

    14 unsigned int regval;

    15 struct resource *res;

    16

    17 printk("led probe ");

    18 /* 1. 获取资源,中断或者内存 */

    19 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    20 if (!res) {

    21 printk("get platform resource failure ");

    22 return -EINVAL;

    23 }

    24

    25 /* 2. 内存映射,并初始化设备 */

    26 led_va = ioremap(res->start, resource_size(res)); /* 内存映射得到虚拟地址 */

    27 regval = readl(led_va + GPF3CON); /* (led_va + GPF3CON) 寄存器的虚拟地址*/

    28 regval &= ~(0xf<<20); /* GPFCON[23:20]清零 */

    29 regval |= 0x1<<20; /* 配置GPF3_5引脚功能为输出 */

    30 writel(regval, led_va + GPF3CON);

    31 regval = readl(led_va + GPF3DAT);

    32 regval |= 0x1<<5; /* 控制GPF3_5输出高电平 */

    33 writel(regval, led_va + GPF3DAT);

    34 return 0; /* 0表示成功,<0表示失败 */

    35 }

    36

    37 int led_remove(struct platform_device *pdev)

    38 {

    39 unsigned int regval;

    40 printk("led remove ");

    41 regval = readl(led_va + GPF3CON); /* (led_va + GPF3CON) 寄存器的虚拟地址*/

    42 regval &= ~(0xf<<20); /* GPFCON[23:20]清零 */

    43 writel(regval, led_va + GPF3CON);

    44 iounmap(led_va);

    45 return 0;

    46 }

    47

    48 /* 用来匹配平台设备的列表 */

    49 const struct of_device_id of_device_table[] = {

    50 {.compatible = "farsight,fs4412-led"},

    51 {}

    52 };

    53

    54 struct platform_driver pdrv = {

    55 .probe = led_probe,

    56 .remove = led_remove,

    57 .driver = {

    58 .owner = THIS_MODULE,

    59 .name = "fs4412-led",

    60 .of_match_table = of_match_ptr(of_device_table),

    61 },

    62 };

    63

    64 static int hello_init(void)

    65 {

    66 printk("Hello, Kernel! ");

    67 return platform_driver_register(&pdrv);

    68 }

    69

    70 static void hello_exit(void)

    71 {

    72 printk("Goodbye, Kernel! ");

    73 platform_driver_unregister(&pdrv);

    74 }

    75

    76 module_init(hello_init); /* 声明模块加载函数 */

    77 module_exit(hello_exit); /* 声明模块卸载函数 */

    78

    79 MODULE_LICENSE("GPL"); /* 声明模块遵守的开源协议 */

    80 MODULE_AUTHOR("zhufeng "); /* 模块作者 */

    81 MODULE_DESCRIPTION("hello module"); /* 模块描述信息 */

  • 相关阅读:
    04月06日总结
    04月07日总结
    03月27日总结
    04月04日总结
    网络编程:阻塞I/O和线程模型
    网络编程:非阻塞I/O
    网络编程:阻塞I/O和进程模型
    bool型返回值函数,没写return语句的时候返回啥?
    网络编程:C10K问题
    网络编程:epoll
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/7783892.html
Copyright © 2020-2023  润新知