設備樹介紹:
設備樹是一個描述設備硬件資源的文件,該文件是由節點組成的樹形結構。如下:
/ {
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\n");
18 /* 1. 獲取資源,中斷或者內存 */
19 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
20 if (!res) {
21 printk("get platform resource failure\n");
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\n");
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!\n");
67 return platform_driver_register(&pdrv);
68 }
69
70 static void hello_exit(void)
71 {
72 printk("Goodbye, Kernel!\n");
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"); /* 模塊描述信息 */