设备树详解
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个dts文件+n个dtsi文件,它们编译而成的dtb文件就是真正的设备树
soc厂商会把soc公共的特性和多块开发板公用的特性提炼为dtsi,而dts则负责描述某个具体的产品(开发板)的特性。dts直接或间接的包含多个dtsi(类似于c语言的头文件),就体现了一个完整的产品(开发板)所有的特性。以solidrun公司的hummingboard为例,其组成为
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;
}
编译设备树
设备树有三种形式:
* 文本文件 (.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文件就是真正的设备树imx6dl-hummingboard.dts |_imx6dl.dtsi | |_imx6qdl.dtsi |_imx6qdl-microsom.dtsi |_imx6qdl-microsom-ar8035.dtsi1
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;
}
相关文章推荐
- 设备树详解
- 设备树详解 (借点引用, &... , 结构, 节点属性设置如gpio的上拉,下拉,io中断设置等 )
- 设备树详解
- 设备树详解
- 设备树详解
- 设备树详解
- 设备树详解(二)
- 设备树历史最详解
- 设备树详解
- 设备树详解(链接很好,作者嵌入式Linux见解深刻)
- 设备树详解
- 设备树详解
- 设备树详解
- 设备树详解
- powerpc 设备树dts 详解
- docker实战1 (docker-toolbox的安装,docker基础命令详解[运行,容器导入/导出,镜像导入/导出,数据卷,网络],构建100个docker实例的测试环境)
- 鹅厂专家详解Android N适配要点
- jQuery的deferred对象详解
- jquery.dataTables插件使用例子详解
- Linux 文件权限详解