您的位置:首页 > 其它

设备树详解

2017-12-14 21:21 776 查看
对于我们大多数人来说,我们用设备树来向内核描述对硬件的添加或删除操作,作为响应,内核就可以加载或卸载相应的驱动。硬件的特殊信息也可以通过设备树来向内核传达。

编译设备树

设备树有三种形式:

* 文本文件 (.dts) - 源

二进制对象 (.dtb) - 目标码

对于设备树,我们一般的使用流程是:编辑DTS文件,然后用一个工具将其编译成DTB文件,这个工具就在Linux内核源码scripts/dtc/目录下。

在Linux3.x版本后,arch/arm/plat-xxx和arch/arm/mach-xxx中,描述板级细节的代码(比如platform_device、i2c_board_info等)被大量取消,取而代之的是设备树,其目录位于arch/arm/boot/dts





1.设备树的组成

1个dts文件+n个dtsi文件,它们编译而成的dtb文件就是真正的设备树


soc厂商会把soc公共的特性和多块开发板公用的特性提炼为dtsi,而dts则负责描述某个具体的产品(开发板)的特性。dts直接或间接的包含多个dtsi(类似于c语言的头文件),就体现了一个完整的产品(开发板)所有的特性。以solidrun公司的hummingboard为例,其组成为
imx6dl-hummingboard.dts
|_imx6dl.dtsi
|   |_imx6qdl.dtsi
|_imx6qdl-microsom.dtsi
|_imx6qdl-microsom-ar8035.dtsi
1
2
3
4
5
此外,dts/dtsi兼容c语言的一些语法,能使用宏定义,也能包含.h文件
相关的API 函数:
//申请gpio的
void lcm_get_gpio_infor(void)

{
static struct device_node *node;

node = of_find_compatible_node(NULL, NULL, "mediatek,lcm_mtk");
        GPIO_LCD_PWR1_EN = of_get_named_gpio(node, "lcm_power1_gpio", 0);
GPIO_LCD_PWR2_EN =
of_get_named_gpio(node, "lcm_power2_gpio", 0);
GPIO_LCD_ic6202_EN =
of_ge
ab6c
t_named_gpio(node, "lcm_i2c_gpio", 0);
gpio_request(GPIO_LCD_PWR1_EN, "lcm_power1_gpio");
gpio_request(GPIO_LCD_PWR2_EN, "lcm_power2_gpio");
gpio_request(GPIO_LCD_ic6202_EN, "lcm_i2c_gpio");
}

gpio_direction_output(tpd_rst_gpio_number, 0); //操作gpio口的函数

当然对应的dtsi文件也要有gpio口操作如下:

&lcm {                               //这里面用了节点间的标号应用
lcm_power1_gpio = <&pio 63 0>;  //这里面用了节点间的包含实现
lcm_power2_gpio = <&pio 64 0>;
        lcm_i2c_gpio = <&pio 55 0>;
};

//对中断操作的API函数

static int tpd_irq_registration(void)
{
struct device_node *node = NULL;
int ret = 0;
u32 ints[2] = { 0, 0 };

GTP_INFO("Device Tree Tpd_irq_registration!");

node =
of_find_matching_node(node, touch_of_match);
if (node) {
of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints));
gpio_set_debounce(ints[0],
ints[1]);

touch_irq = irq_of_parse_and_map(node, 0);
GTP_INFO("Device gt1x_int_type = %d!", gt1x_int_type);
if (!gt1x_int_type) {/*EINTF_TRIGGER*/
ret =
    request_irq(touch_irq, (irq_handler_t) tpd_eint_interrupt_handler, IRQF_TRIGGER_RISING,
"TOUCH_PANEL-eint", NULL);
if (ret > 0) {
ret = -1;
GTP_ERROR("tpd request_irq IRQ LINE NOT AVAILABLE!.");
}
} else {
ret =
    request_irq(touch_irq, (irq_handler_t) tpd_eint_interrupt_handler, IRQF_TRIGGER_FALLING,
"TOUCH_PANEL-eint", NULL);
if (ret > 0) {
ret = -1;
GTP_ERROR("tpd request_irq IRQ LINE NOT AVAILABLE!.");
}
}
} else {
GTP_ERROR("tpd request_irq can not find touch eint device node!.");
ret = -1;
}

GTP_INFO("[%s]irq:%d,
debounce:%d-%d:", __func__, touch_irq, ints[0], ints[1]);
return ret;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: