基于pinctrl 和 devcice tree的SOC GPIO 使用

在嵌入式系统开发中,我们不可避免的要跟SOC 的GPIO模块打交道。在单片机的开发中,我们一般使用的是下面的模式

void XXX_init()

{

//gpio fuction mux select


//peripheral regsiter configure


//other related software resourece init


}

其实在早期的linux系统中,外设的初始化也是一个类似的过程,只不过是要使用linux提供提供的一些接口而已,不像单片机可以随心所欲的写code


但是随着linux的发展 device tree已经慢慢统治了powerpc linux和arm linux。就使用来说,的确是简单了很多,但是linux引入了大量的框架来支持这些便利,要多了一些需要精读的代码,这里不分析代码实现的细节,只是从使用的角度来记录一下,方便以后的工作中,查询使用。

这里分三种情况来举例说明

1. 外围控制器的mux功能选择,以IPQ409的SPI控制器举例,这里主要用的是PINCTRL 的MUX 设定

要想把某组pin分配给SPI0控制器,需要在dts里做如下定义:

1).定义一个pn mux

spi_0_pins: spi_0_pinmux {
mux {
pins = "gpio12", "gpio13", "gpio14", "gpio15"; //pin列表,可以查看芯片手册获取这个group
function = "blsp_spi0";
bias-disable;
};

2).在spi的控制器节点引用之

spi_0: spi@78b5000 {

/* BLSP1 QUP1 */
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "ok";



m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <24000000>;
use-default-sizes;
};
};

2. 定义pin为gpio,并设置默认的 输入输出属性已经上下拉配置以及驱动电流等

dts文件里在pinctrl节点下添加以下定义,可以定义若干pin group,或者只对某个pin做特殊的描述,

gpio可以配置的属性如下:


 bias-disable – disable any pin bias
 bias-pull-up – pull up the pin
 bias-pull-down – pull down the pin
 drive-strength – sink or source at most X mA
 input-enable – enable input on pin (no effect on output)
 input-disable – disable input on pin (no effect on output)
 output-low – set the pin to output mode with low-level
 output-high – set the pin to output mode with high-level

 pinctrl@0x01000000 {
            pinctrl-0 = <&example_gpio>;
            pinctrl-names = "default";


            ............
            example_gpio: hw_gpio{
                led{
                    pins = "gpio37","gpio42","gpio51","gpio52","gpio61","gpio68";
                    output-low;
                };
                gpio{
                    pins = "gpio49";
                    output-high;
                };
                gpio_i2c{
                    pins = "gpio21","gpio20";
                    drive-strength = <4>;
                };
            };
          .................

};

3. 在某个device node需要使用gpio,或者使用gpio作为中断输入

这里以一个GPIO模拟的I2C控制器举例

i2c_1 {
        compatible = "atmel,i2c-gpio";
        status = "ok";
        gpios = <&tlmm 21 0      &tlmm 20 0>; /*i2c pin */
        i2c-gpio,delay-us = <2>;
        i2c-gpio,scl-open-drain;
        #address-cells = <1>;
        #size-cells = <0>;

        isl28022@40 {
                /* power monitor */
                compatible = "isl,isl28022";
                reg = <0x40>;

              /*use gpio 43 as gpio interrupt,tlmm is the gpio controller defined in the example soc system*/

                interrupt-parent = <&tlmm>;
                interrupts = <43 0x8>;
                irq-gpio = <&tlmm 43 0>;

        };


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设备树(device tree)机制是Linux内核从linux-3.x版本开始引进的一种机制,目的是解决内核源码的arch/arm目录下代码混乱的问题:随着ARM生态的快速发展,在内核源码的arch/arm目录下,存放着几十种arm芯片和几百个开发板相关的源文件,很多开发板和处理器的中断、寄存器等相关硬件资源都在这个目录下以.c或.h的文件格式定义。而对于内核来说,与这些硬件耦合,会导致内核代码混乱不堪,每个开发板上运行的内核镜像都必须单独编译配置,无法通用。什么时候Linux内核能像Windows镜像那样,无论你的电脑什么配置,一个Windows安装包,都可以直接下载安装运行呢?设备树机制,实现了Linux内核和硬件平台的解耦:每个硬件平台的硬件资源使用一个设备树文件(xxx.dts)来描述,而不是在arch/arm下以.c 或 .h 文件来定义。Linux内核是一个通用的内核,在启动过程中,在通过解析设备树中的硬件资源来初始化某个具体的平台。 引入设备树后,很多和内核驱动开发的工作也发生了变化:以往驱动工程师关注的头文件宏定义、寄存器定义,现在这些基本上不用关注,关注的重点则转向了如何根据硬件平台去配置和修改设备树文件。很多驱动的编程接口也发生了变化,开始慢慢使用device tree提供的编程接口去开发驱动。本期课程主要面向嵌入式开发人员,分享Linux下驱动开发所需要的设备树知识和必备技能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值