本篇内容为devicetree部分gpio相关宏定义功能及使用说明
目录为:ncs\zephyr\include\devicetree\gpio.h
关于gpio的PIN及Flag说明:
* gpio1: gpio@... {
* compatible = "vnd,gpio";
* #gpio-cells = <2>;
* };
*
* gpio2: gpio@... {
* compatible = "vnd,gpio";
* #gpio-cells = <2>;
* };
*
* n: node {
* gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
* <&gpio2 30 GPIO_ACTIVE_HIGH>;
* };
这里用到了#gpio-cells
,介绍下#gpio-cells
的概念
gpio可以有两个参数,分别是PIN和Flag,PIN脚说明了该gpio的引脚位置,flag则描述该引脚是高电平还是低电平有效。#gpio-cells
的值决定了gpio的参数的个数,以上面的dts文件为例,这里面#gpio-cells
的值为2,所以后面<&gpio1 10 GPIO_ACTIVE_LOW>
会有PIN和flag两个参数,也就是<&gpio1 10 GPIO_ACTIVE_LOW>
里面的pin脚是10,GPIO_ACTIVE_LOW
这两个参数,如果#gpio-cells
的值为1,那么这里只需要写成<&gpio1 10>
即可。
1,DT_GPIO_LABEL_BY_IDX(node_id, gpio_pha, idx)
从node id的gpio phandle-array的属性索引idx处获取它的label属性。
如果GPIO控制器节点在node_id 的 “gpio_pha”属性索引“idx”处没有标签属性,将会报错。
* gpio1: gpio@... {
* label = "GPIO_1";
* };
*
* gpio2: gpio@... {
* label = "GPIO_2";
* };
*
* n: node {
* gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
* <&gpio2 30 GPIO_ACTIVE_HIGH>;
* };
对于上述dts文件,使用如下指令,可以获取到gpio2的label “GPIO_2”。
DT_NODELABEL(n)等宏功能可以参考《devicetree.h常用宏定义使用说明》
DT_GPIO_LABEL_BY_IDX(DT_NODELABEL(n), gpios, 1)
2,DT_GPIO_LABEL(node_id, gpio_pha)
获取node id 的gpio phandle-array属性的索引0处的label属性,等同于DT_GPIO_LABEL_BY_IDX(node_id, gpio_pha, 0)
* gpio1: gpio@... {
* label = "GPIO_1";
* };
*
* gpio2: gpio@... {
* label = "GPIO_2";
* };
*
* n: node {
* gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
* <&gpio2 30 GPIO_ACTIVE_HIGH>;
* };
对于上述dts文件,使用DT_GPIO_LABEL(DT_NODELABEL(n), gpios)
,可以获取到gpio1的label属性值"GPIO_1".
3,DT_GPIO_PIN_BY_IDX(node_id, gpio_pha, idx)
通过node id的gpio属性描述符的索引idx处获取它的引脚号。
这个宏仅适用于具有名字为"pin"的gpio属性的指示符
* gpio1: gpio@... {
* compatible = "vnd,gpio";
* #gpio-cells = <2>;
* };
*
* gpio2: gpio@... {
* compatible = "vnd,gpio";
* #gpio-cells = <2>;
* };
*
* n: node {
* gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
* <&gpio2 30 GPIO_ACTIVE_HIGH>;
* };
DT_GPIO_PIN_BY_IDX(DT_NODELABEL(n), gpios, 0) // 10
DT_GPIO_PIN_BY_IDX(DT_NODELABEL(n), gpios, 1) // 30
对于上面的dts文件,上面两条指令分别获取了gpio1和gpio2的pin脚的值10和30。
4,DT_GPIO_PIN(node_id, gpio_pha)
获取node id的gpio属性索引0处的引脚号,等同于DT_GPIO_PIN_BY_IDX(node_id, gpio_pha, idx)
* gpio1: gpio@... {
* compatible = "vnd,gpio";
* #gpio-cells = <2>;
* };
*
* gpio2: gpio@... {
* compatible = "vnd,gpio";
* #gpio-cells = <2>;
* };
*
* n: node {
* gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
* <&gpio2 30 GPIO_ACTIVE_HIGH>;
* };
DT_GPIO_PIN(DT_NODELABEL(n), gpios) // 10
对于上述dts文件,上面的指令获取了gpio1的pin脚位置10
5,DT_GPIO_FLAGS_BY_IDX(node_id, gpio_pha, idx)
通过node id的gpio属性描述符的索引idx处获取它的flag状态。
这个宏只适用于gpio属性具有flag
参数,也就是要求#gpio-cells
的值为2,否则会返回0
* gpio1: gpio@... {
* compatible = "vnd,gpio";
* #gpio-cells = <2>;
* };
*
* gpio2: gpio@... {
* compatible = "vnd,gpio";
* #gpio-cells = <2>;
* };
*
* n: node {
* gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
* <&gpio2 30 GPIO_ACTIVE_HIGH>;
* };
* DT_GPIO_FLAGS_BY_IDX(DT_NODELABEL(n), gpios, 0) // GPIO_ACTIVE_LOW
* DT_GPIO_FLAGS_BY_IDX(DT_NODELABEL(n), gpios, 1) // GPIO_ACTIVE_HIGH
对于上面的dts文件,使用上述指令,可以获取到gpio1和gpio2的flag状态,分别是GPIO_ACTIVE_LOW
和GPIO_ACTIVE_HIGH
6,DT_GPIO_FLAGS(node_id, gpio_pha)
通过node id的gpio属性描述符的索引0处获取它的flag状态,等同于 DT_GPIO_FLAGS_BY_IDX(DT_NODELABEL(n), gpios, 0)
7,DT_INST_GPIO_LABEL_BY_IDX(inst, gpio_pha, idx)
通过DT_DRV_COMPAT instance的具有gpio_pha属性的索引idx获取它的label属性值。参数分别是DT_DRV_COMPAT
的instance number,gpio属性名称,索引下标。
DT_DRV_COMPAT用法参考DT_DRV_COMPAT
test_nodelabel: TEST_NODELABEL_ALLCAPS: test_gpio_1: gpio@deadbeef {
compatible = "vnd,gpio";
gpio-controller;
reg = < 0xdeadbeef 0x1000 >;
#gpio-cells = < 0x2 >;
#foo-cells = < 0x1 >;
label = "TEST_GPIO_1";
interrupts = <4 3>;
status = "okay";
};
test_phandles: phandle-holder-0 {
compatible = "vnd,phandle-holder";
gpios = <&test_gpio_1 10 20>, <&test_gpio_2 30 40>;
};
对于上面的dts文件,如果不存在其他的compatible名字为 “vnd,phandle-holder”,那么可以通过下面代码获取到test_gpio_1的label属性值。
#define DT_DRV_COMPAT vnd_phandle_holder
DT_INST_GPIO_LABEL_BY_IDX(0, gpios, 0) //"TEST_GPIO_1"
这里定义DT_DRV_COMPAT
的值为vnd_phandle_holder
,注意,这里的下划线,对应在dts文件里有可能时,
或者-
,也就是对应于dts文件里的compatible = "vnd,phandle-holder"
然后通过在dts文件里找到的第一个compatible="vnd,phandle-holder"
的节点的gpios属性的第一个值test_gpio_1
,然后去找到它的对应的label,也就是"TEST_GPIO_1"
8,DT_INST_GPIO_LABEL_BY_IDX(inst, gpio_pha)
等同于DT_INST_GPIO_PIN_BY_IDX(inst, gpio_pha, 0)
,参考第7条的用法介绍。
9,DT_INST_GPIO_PIN_BY_IDX(inst, gpio_pha, idx)
用法和第七条基本一致,区别时第七条获取的是对应gpio的label属性值,而此处时获取对应gpio的PIN值。
test_phandles: phandle-holder-0 {
compatible = "vnd,phandle-holder";
gpios = <&test_gpio_1 10 20>, <&test_gpio_2 30 40>;
};
#define DT_DRV_COMPAT vnd_phandle_holder
DT_INST_GPIO_PIN_BY_IDX(0, gpios, 0) // 10
对于上述指令,获取到的时test_gpio_1
的PIN值,也就是10
10,DT_INST_GPIO_PIN(inst, gpio_pha)
等同于DT_INST_GPIO_PIN_BY_IDX(0, gpios, 0)
,用法参考第9条。
11,DT_INST_GPIO_FLAGS_BY_IDX(inst, gpio_pha, idx)
用法与第七条基本一致,区别是本条获取的是对应gpio属性的FLAG值。
test_phandles: phandle-holder-0 {
compatible = "vnd,phandle-holder";
gpios = <&test_gpio_1 10 20>, <&test_gpio_2 30 40>;
};
#define DT_DRV_COMPAT vnd_phandle_holder
DT_INST_GPIO_FLAGS_BY_IDX(0, gpios, 0) //
对于上述指令,获取到的时test_gpio_1
的FLAG值,也就是20
12,DT_INST_GPIO_FLAGS(inst, gpio_pha)
等同于DT_INST_GPIO_FLAGS_BY_IDX(0, gpios, 0)
,用法参考第11条。