设备树详解

来源:互联网 发布:中学生网络文明公约 编辑:程序博客网 时间:2024/05/29 15:39

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

编译设备树
设备树有三种形式:
* 文本文件 (.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_get_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;
}





原创粉丝点击