设备树的一些知识点
来源:互联网 发布:80端口被系统占用 编辑:程序博客网 时间:2024/06/07 06:36
参考网址:http://www.wowotech.net/linux_kenrel/pin-controller-driver.html
可寻址的设备使用如下信息来在Device Tree中编码地址信息:
- reg
- #address-cells
- #size-cells
其中reg的组织形式为reg = <address1 length1 [address2 length2] [address3 length3] ... >,其中的每一组address length表明了设备使用的一个地址范围。address为1个或多个32位的整型(即cell),length表示长度。address 和 length 字段是可变长的,父结点的#address-cells和#size-cells分别决定了子结点reg属性的address和length字段的长度。在本例中:
root结点的#address-cells = <1>;和#size-cells = <1>;决定了serial、gpio、spi等结点的address和length字段的长度分别为1。
cpus 结点的#address-cells = <1>;和#size-cells = <0>;决定了2个cpu子结点的address为1,而length为空,于是形成了2个cpu的reg = <0>;和reg = <1>;
external-bus结点的#address-cells = <2>和#size-cells = <1>;决定了其下的ethernet、i2c、flash的reg字段形如reg = <0 0 0x1000>;、reg = <1 0 0x1000>;和reg = <2 0 0x4000000>;。其中第一个cell(0、1、2)是对应的片选,第2个cell(0,0,0)是相对该片选的基地址,第3个cell(0x1000、0x1000、0x4000000)为length。特别要留意的是i2c结点中定义的 #address-cells = <1>;和#size-cells = <0>;并且作用到了I2C总线上连接的RTC,它的address字段为0x58,是设备的I2C地址。
root结点的子结点描述的是CPU的视图,因此root子结点的address区域就直接位于CPU的memory区域。但是,经过总线桥后的address往往需要经过转换才能对应的CPU的memory映射。external-bus的ranges属性定义了经过external-bus桥后的地址范围如何映射到CPU的memory区域。
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet 1 0 0x10160000 0x10000 // Chipselect 2, i2c controller 2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flashranges是地址转换表,子地址空间的#address-cells为2,父地址空间的#address-cells值为1,因此0 0 0x10100000 0x10000的前2个cell为external-bus片选0上偏移0,第3个cell表示把前面的地址空间映射到CPU的0x10100000位置,第4个cell表示映射的大小为0x10000。
interrupt-controller
interrupt-controller – 这个属性为空,中断控制器应该加上此属性表明自己的身份;
#interrupt-cells – 与#address-cells 和 #size-cells相似,它表明连接此中断控制器的设备的interrupts属性的cell大小。
在整个Device Tree中,与中断相关的属性还包括:
interrupt-parent – 设备结点透过它来指定它所依附的中断控制器的phandle,当结点没有指定interrupt-parent 时,则从父级结点继承。对于本例而言,root结点指定了interrupt-parent = <&intc>;其对应于intc: interrupt-controller@10140000,而root结点的子结点并未指定interrupt-parent,因此它们都继承了intc,即位于0x10140000的中断控制器。
interrupts – 用到了中断的设备结点透过它指定中断号、触发方法等,具体这个属性含有多少个cell,由它依附的中断控制器结点的#interrupt-cells属性决定。而具体每个cell又是什么含义,一般由驱动的实现决定,而且也会在Device Tree的binding文档中说明。譬如,对于ARM GIC中断控制器而言,#interrupt-cells为3,它3个cell的具体含义Documentation/devicetree/bindings/arm/gic.txt就有如下文字说明:
01 The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI 02 interrupts. 03 04 The 2nd cell contains the interrupt number for the interrupt type. 05 SPI interrupts are in the range [0-987]. PPI interrupts are in the 06 range [0-15]. 07 08 The 3rd cell is the flags, encoded as follows: 09 bits[3:0] trigger type and level flags. 10 1 = low-to-high edge triggered 11 2 = high-to-low edge triggered 12 4 = active high level-sensitive 13 8 = active low level-sensitive 14 bits[15:8] PPI interrupt cpu mask. Each bit corresponds to each of 15 the 8 possible cpus attached to the GIC. A bit set to '1' indicated 16 the interrupt is wired to that CPU. Only valid for PPI interrupts.另外,值得注意的是,一个设备还可能用到多个中断号。对于ARM GIC而言,若某设备使用了SPI的168、169号2个中断,而且都是高电平触发,则该设备结点的interrupts属性可定义为:interrupts = <0 168 4>, <0 169 4>;
一个典型的device tree中的外设node定义如下:
下面的伪代码描述了S3C2416 pin controller 的DTS结构:device-node-name {
定义该device自己的属性pinctrl-names = "sleep", "default";
pinctrl-0 = ;
pinctrl-1 = ;
};
pinctrl@56000000 { 定义S3C2416 pin controller自己的属性 定义属于S3C2416 pin controller的pin configurations }
samsung 24xx系列SOC的pin controller的pin configurations包括两类,一类是定义pin bank,另外一类是定义功能复用配置。第一类如下: pinctrl@56000000 { 定义S3C2416 pin controller自己的属性 …… gpf { gpio-controller; #gpio-cells = <0x2>; interrupt-controller; #interrupt-cells = <0x2>; linux,phandle = <0xc>; phandle = <0xc>; }; …… }
每个pin configuration都是pin controller的child node,描述了client device要使用到的一组pin的配置信息。具体如何定义pin configuration是和具体的pin controller相关的。
phandle(linux,phandle这个属性和phandle是一样的,只不过linux,phandle是old-style,多定义一个属性是为了兼容)定义了一个句柄,当其他的device node想要引用这个node的时候就可以使用该句柄。
第二类如下:
uart的pin configuration,代码如下:
pinctrl@56000000 { 定义S3C2416 pin controller自己的属性 …… uart0-data { samsung,pins = "gph-0", "gph-1"; samsung,pin-function = <0x2>; linux,phandle = <0x2>; phandle = <0x2>; }; uart0-fctl { samsung,pins = "gph-8", "gph-9"; samsung,pin-function = <0x2>; linux,phandle = <0x3>; phandle = <0x3>; }; …… }
samsung,pins这个属性定义了一个pin configuration所涉及到的引脚。
对于uart0-data这个node,该配置涉及了gph bank中的第一个和第二个GPIO pin。一旦选择了一个功能,那么samsung,pins定义的所有的引脚都需要做相应的功能设定,那么具体设定什么值呢?这就是samsung,pin-function定义的内容了。而具体设定哪个值则需要去查阅datasheet了。对于uart0-data,向gph bank中的第一个和第二个GPIO pin对应的配置寄存器中写入2就可以把这两个pin定义为uart功能。
3.client device的DTS
device-node-name { 定义该device自己的属性 pinctrl-names = "sleep", "active";------(1) pinctrl-0 = <pin-config-0-a>;--------------(2) pinctrl-1 = <pin-config-1-a pin-config-1-b>; };
(1)pinctrl-names定义了一个state列表。那么什么是state呢?对于一个client device,它使用了一组pin,这一组pin应该同时处于某种状态,毕竟这些pin是属于一个具体的设备。state的定义和电源管理关系比较紧密,例如当设备active的时候,我们需要pin controller将相关的一组pin设定为具体的状态,而当设备进入sleep状态的时候,需要pin controller将相关的一组pin设定为普通GPIO。state有两种标识,一种就是pinctrl-names定义的字符串列表,另外一种就是ID。ID从0开始,依次加一。根据例子中的定义,state ID等于0(名字是active)的state对应pinctrl-0属性,state ID等于1(名字是idle)的state对应pinctrl-1属性。具体设备的state的定义请参考在自己的device bind。
(2)pinctrl-x的定义。pinctrl-x是一个句柄(phandle)列表,每个句柄指向一个pin configuration。有时候,一个state对应多个pin configure。例如在active的时候,I2C功能有两种配置,一种是从pin ID{7,8}引出,另外一个是从pin ID{69,103}引出。
我们选取samsung串口的dts定义如下:
serial@50000000 { …… pinctrl-names = "default"; pinctrl-0 = <0x2 0x3>; };该serial device只定义了一个state就是default,对应pinctrl-0属性定义。pinctrl-0是一个句柄(phandle)列表,每个句柄指向一个pin configuration。0x2对应上节中的uart0-data节点,0x03对应uart0-fctl 节点,也就是说,这个串口有两种配置,一种是从gph bank中的第一个和第二个GPIO pin引出,另外一个是从gph bank中的第8个和第9个GPIO pin引出。
- 设备树的一些知识点
- 设备树的一些知识点
- Driver: 跟设备驱动相关的一些知识点
- 树的一些知识点总结
- Hibernate的一些知识点
- c#的一些知识点
- sim300的一些知识点
- GDI的一些知识点
- IFRAME的一些知识点
- PHP的一些知识点
- python 的一些知识点
- 一些常用的知识点
- 静态的一些知识点
- django的一些知识点
- Jquery的一些知识点
- ios的一些知识点
- ios的一些知识点
- ios的一些知识点
- Excel——如何使用VBA操作单元格的格式
- mysql增加constraint,_查看schema总结
- 重装系统备份
- JNIEnv 结构参考
- fedora 22 发行说明摘要
- 设备树的一些知识点
- mysql和oracle区别
- [web安全] 定制安全的PHP环境
- Java 性能优化实战记录(1)---定位并分析耗cpu最多的线程
- Cocos2d-x 3.2 异步动态加载
- rvm
- tpl使用foreach
- spring txManager配置
- Tracking-Learning-Detection原理分析