设备树:顾名思义利用树形结构描述设备的文件。
Pinctrl:依据Linux设计分离的思想,简化驱动对芯片引脚的控制。驱动通过pinctrl来控制引脚,各个芯片厂家已经对pinctrl相关代码封装好了。只需要通过文档直接调用相关API即可,大大简化了驱动编写的工作量。
查找相关文档:由于每个厂家的硬件不一样,所以使用方法也略有差异,我们需要通过相关文档查看官方给出的例程。路径为内核目录下的/Documentation/devicetree/bindings/pinctrl
我使用的是三星的芯片,因此只关注samsung-pinctrl.txt
在Pinctrl中添加需要的引脚:打开文件arch/arm/boot/dts/exynos4412-pinctrl.dtsi
自己创建的设备树节点添加的位置,我使用的是 L0-2引脚。
打开4412的datasheet如下:
L0的基地址为0x11000000,因此需要寻找dtsi文件中对应的一级设备树节点。
在官方源码中发现pinctrl1的一级节点地址与之对应。因此我们需要将自己的节点添加到这里。如下所示:
/*添加自己需要用得到的引脚,添加到pinctrl_1下,和1级节点的地址有关,不要加错地方!*/
my_gpio1_high:my_gpio1_high {
samsung,pins = "gpl2-0" ; /*引脚为l2-0*/
samsung,pin-function = <1>; /*引脚功能设置为输出模式 */
samsung,pin-val = <1>; /*引脚初始值设置为1*/
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>; /*引脚设置为上拉模式*/
};
my_gpio1_low:my_gpio1_low {
samsung,pins = "gpl2-0" ; /*引脚为l2-0*/
samsung,pin-function = <1>; /*引脚功能设置为输出模式 */
samsung,pin-val = <0>; /*引脚初始值设置为0*/
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>; /*引脚设置为上拉模式*/
};
这样仅仅是添加了和pinctrl相关的节点,我们还要再设备树的根节点下添加供自己编写的驱动调用的设备树节点。
在相同目录下我们打开文件arch/arm/boot/dts/exynos4412-itop-elite.dts 在根节点下创建自己的一级子节点。
这里需要注意的是此处的pinctrl-0和上面添加代码的pinctrl不是一个意思。这里的pinctrl-0表示对应的pinctrl-name的第一个属性值,如果pinctrl-name有多个属性值,用逗号隔开。那么各个属性值按顺序会依次对应 pinctrl-0,pinctrl-1,pinctrl-2 ………
到这里我们设备树添加设备相关的工作就已经做完。
在内核目录下使用 make dtbs 编译修改后的设备树文件,如果报错可以使用root模式再次尝试,把生成的exynos4412-itop-elite.dtb 文件更新到芯片。打开超级终端查看是否设置成功。
在超级终端中进入linux根文件系统:
在/proc/device-tree目录下有所有的node的信息表明节点已经创建成功
在/sys/devices/platform/目录下有所有设备node的信息。表明设备注册了,最后驱动才能进入probe
编写对应驱动调用GPIO
这里我们需要在代码中编写两部分内容
1:杂项设备的注册,这样才可以生成设备节点供上层应用调用
2:注册驱动,注册驱动的compatible与设备树中的匹配才能调用驱动
驱动源代码如下:
#include <linux/ini