device tree

最近在搞wota艺,虽然不如岛国那么有底蕴,但是更疯狂, 我不知道该怎么说,说啥好。。。

1、随便说一下

我有一种感觉就是配置表。。。废话,如果比较暴力一点的调试直接用 io 指令,你们配完没有,一个指令也可以完成

io -4 -w 0xff7b0004 0x00ff000f  。。。类似这种,这就是一种方法,一种方法

最常使用的是引脚,也有其它各种寄存器

按照probe的最先加载的一次性初始化,或者针对引脚rfkill中的block管理,这也是一种方法,方法归方法,最终是要module来实现的

 

按照最原始的方法,比如以前的单机游戏写一个 gpio.c gpio.h  再写一个pinctrl.c pinctrl.h 就是对pin脚的两个module了,然后其它module要初始自己要用的引脚时,直接调用就可以了,对着dts表来设置

 

说了那么久,还是不知道dts是什么,是一个表,一个文件,打包放在emmc的boot分区,或者其它分区。。反正要放

名字有各种

 

比如xxx.dtb 

在kernel  

make xxx.dtb 就可以得到

在kernel我一般看是

./scripts/dtc/dtc -I dtb -O dts -o xxx.dts arch/arm/boot/dts/xxx.dtb

这个dts由dtb反编译出来看,就是真正的dts了,纯净的,没有包各种dtsi那么恶心,看着很舒服,看看

拿串口来说,都是数字了,其它什么引用板级测试也净化了xxx:[email protected]  比如xxx这种乱七八糟的。。

vi  xxx.dts

 

        [email protected] {
                compatible = "rockchip,serial";
                reg = <0xff180000 0x100>;
                interrupts = <0x0 0x37 0x4>;
                clock-frequency = <0x16e3600>;
                clocks = <0x9a 0x8f 0x8>;
                clock-names = "sclk_uart", "pclk_uart";
                reg-shift = <0x2>;
                reg-io-width = <0x4>;
                dmas = <0x90 0x1 0x90 0x2>;
                #dma-cells = <0x2>;
                pinctrl-names = "default";
                pinctrl-0 = <0x9b 0x9c>;
                status = "okay";
                dma-names = "!tx", "!rx";
        };
 

 

compatible很重要,属于查询第一条件,但是reg更重要,类似我的io了,多个匹配的时候,就用reg来区分了

串口的moudle会去读                

                interrupts = <0x0 0x37 0x4>;
                clock-frequency = <0x16e3600>;
                clocks = <0x9a 0x8f 0x8>;

pinctrl module会去读

                pinctrl-names = "default";
                pinctrl-0 = <0x9b 0x9c>;

 

 

也都很简单的,就是读一下而已,没什么感觉

 

2、单独说一下pinctrl(复用)

复用就是说引脚不够用,一个引脚充当多个角色的意思

pinctrl-names = "default"; 这个有点调皮,多了一个自己的形态,不过也不难,

 

default 意思是状态,意思是状态,意思是状态,意思是状态,意思是状态,意思是状态!

就是默认状态,

pinctrl-0 = <0x9b 0x9c>;

                        uart0-xfer {
                                rockchip,pins = <0x4c01 0x4c11>;
                                rockchip,pull = <0x4>;
                                rockchip,drive = <0x0>;
                                linux,phandle = <0x9b>;
                                phandle = <0x9b>;
                        };
 

反编译过来真好,直接就看到0x9b 是设置tx rx 引脚

<0x4c01 0x4c11>

这两个数字有没有什么逻辑。。。pinctrl   module有什么感觉

答案是没有

XDD,只是一个宏而已

device tree

 

。。。。这个就无解了,毕竟是宏,给pinctrl module看就可以了

 

0x4c00的时候tx引脚就是设置成为gpio  0x4c01就是设置成为uart了  

 

 

再看一个其他的
 

 pinctrl-names = "default", "rts_gpio";
                pinctrl-0 = <0x114>;
                pinctrl-1 = <0x115>;
 

 

这个就是两种状态了喔

 

看一个rfkill的代码

 

if (!IS_ERR(data->pinctrl)) {
data->rts_gpio.default_state = pinctrl_lookup_state(data->pinctrl, "default");
data->rts_gpio.gpio_state = pinctrl_lookup_state(data->pinctrl, "rts_gpio");
} else {
data->pinctrl = NULL;
LOG("%s: dts does't define the uart rts iomux.\n", __func__);
//return -EINVAL;
}

 

pinctrl_lookup_state!!!!!!

会去查找状态,比如说状态1 的时候设置成为普通的串口,状态2 设置成为普通的gpio

好比两种选择,吃猪肚鸡或者吃椰子鸡,两种状态都是它,功能不一样,补肾或者补心,我比较喜欢吃椰子鸡,香甜,脆嫩

 

pinctrl_lookup_state就是会去找这种状态,要用就module上写好了

 

最后

pinctrl_select_state(pinctrl, rts->gpio_state);
gpio_direction_output(rts->io, !rts->enable);

 

直接调用pinctrl_select_state,就会去设置引脚复用寄存器了,没了

是不是搞了那么多还不如我一个io指令下去,别,这是上层

 

 

3、我还是比较喜欢io指令。。。。

用这个就要抛开所有,直接看手册了,不过dts上面的reg还是可以参考一下