设为首页 收藏本站
查看: 758|回复: 0

[经验分享] Linux 内核层和 用户层 配置 GPIO 引脚

[复制链接]

尚未签到

发表于 2017-11-18 06:56:31 | 显示全部楼层 |阅读模式
  Linux BSP 开发的基础就是和GPIO打交道, 下面总结下这几天对某家开发板的GPIO控制的知识。
  公司的开发板用的是 DTB  模式 ,首先,进入 dts,dtsi文件查看关于GPIO 的模块。



soc {
.
.
.
gpio0: gpio@****addr {
compatible = "**********";
reg = <0 0x****addr 0 0x50>;
interrupts = <SPI 4 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
gpio-ranges = <&pfc 0 0 16>;
#interrupt-cells = <2>;
interrupt-controller;
clocks = <&cpg CPG_MOD 912>;
power-domains = <*****>;
};
.
.
.
};
  可以看到 GPIO 节点 挂在 SOC node 下 ,手上这块开发板 把GPIO分成了8个 bank  :  gpio0 - gpio7
  reg =<0 地址 0 长度>
  #gpio-cells  =<2> 表示 要用2个cell描述一个 GPIO引脚
  如 I2C中定义 :  pwd-gpios  = <&gpio6 7 GPIO_ACTIVE_HIGH>;
  表示 bank 6 的gpio  用 2个cell 描述  :7,GPIO_ACTIVE_HIGH (7表示bank 6 下的第七个引脚一般是 GP 6_07表示  ;GPIO_ACTIVE_HIGH则为高电平有效)     
  gpio-controller;  interrupt-controller; 表示 bank 0 下的引脚 既可以作为中断引脚 ,也可以作为 通用的GPIO引脚
  gpio-ranges = <&pfc 0 0 16>;  表示 bank 0下有16个 GPIO引脚
DSC0000.png

  GPIO 使用 pinctrl 方式来驱动 ,pin control subsystem 会 :
  1. 枚举所有可用的pin 脚   ,于是每个引脚就有的唯一的 ID (num) ,这个ID 很关键,对于以后的操作。



enum {
PINMUX_RESERVED = 0,
PINMUX_DATA_BEGIN,
GP_ALL(DATA), /* add GP_0_1_DATA  ,GP_0_1_DATA..... */
PINMUX_DATA_END,
#define F_(x, y)
.....
}
  2.管理 这些Pin脚的, 由于pin 可以复用 比如 SPI 和GPIO 复用一个pin脚 如:  GP2_08 / MISO,于是引申出 pin group 和 pin functon 两个概念:



    i2c2_pins: i2c2 {
groups = "i2c2_a";
function = "i2c2";
};
  在dts 中如上所示 ,其中 i2c2_a 在 pinctl 源码中 如下所示,i2c的两根引脚使用 GP5_0 ,GP5_4.



static const unsigned int i2c2_a_pins[] = {
/* SDA, SCL */
GP_PIN(5, 0),GP_PIN(5, 4),
};
  function 如下 :



struct sh_pfc_function {
const char *name;
const char * const *groups;
unsigned int nr_groups;
};
#define SH_PFC_FUNCTION(n = i2c2)                \
{                        \
.name = #n,                \
.groups = n##_groups,            \
.nr_groups = ARRAY_SIZE(n##_groups),    \
}
  好了 ,基本概念就先写这么多  。

内核层配置 GPIO
  在 写内核驱动的时候 如果希望配置某个GPIO引脚 , 可以在dts中 添加:  pwd-gpios  = <&gpio0 7 GPIO_ACTIVE_HIGH>;
  在 driver 代码中 ,  需要包含 #include <linux/gpio.h>使用 :
  gpio_id = of_get_named_gpio(your_driver->dev->of_node,"pwd-gpios", 0);
  获取 GP0_07的 ID号 ,然后申请 一个GPIO 操作对象。
  if (gpio_is_valid(gpio_id))  //判断一个IO是否合法
  devm_gpio_request_one(&platform_device->dev, gpio_id,GPIOF_OUT_INIT_LOW, name);
  设置GPIO的方向,如果是输出同时设置电平:
    /* set as input or output, returning 0 or negative errno */
    int gpio_direction_input(unsigned gpio);
    int gpio_direction_output(unsigned gpio, int value);
  获取输入引脚的电平:
    /* GPIO INPUT: return zero or nonzero */
    int gpio_get_value(unsigned gpio);
  设置输出:
    void gpio_set_value(unsigned gpio, int value);
  释放申请的GPIO对象 
  void gpio_free(unsigned gpio);
  将GPIO映射为IRQ中断:
    /* map GPIO numbers to IRQ numbers */
    int gpio_to_irq(unsigned gpio);
  /* map IRQ numbers to GPIO numbers (avoid using this) */
    int irq_to_gpio(unsigned irq);
  设置GPIO IRQ中断类型:
  set_irq_type(gpio_to_irq( gpio), IRQ_TYPE_EDGE_FALLING);

用户层配置 GPIO
  需要确认  内核  menuconfig  中 Device Drivers -》  GPIO Support  设 y .
  在 /sys/class/gpio  目录下如下所示 :



root@salvator-x:/sys/class/gpio# ls
export         gpiochip361  gpiochip419  gpiochip453  gpiochip496
gpiochip357  gpiochip393  gpiochip437  gpiochip468  unexport
  gpiochip 后面的数字 是每个bank 的基地址  也就是  GP0 对应 gpiochip468
  那么  GP0_07 的 ID 就是  468 + 7 ;(可能不同的内核版本,或者 开发板不一样 )通过 :



root@salvator-x:/sys/class/gpio# echo 475 > export
  会对应生成 gpio475 目录



root@salvator-x:/sys/class/gpio/gpio475# ls
active_low  device  direction  edge  power  subsystem  uevent  value
  通过



root@salvator-x:/sys/class/gpio/gpio475# echo 1 >value
root@salvator-x:/sys/class/gpio/gpio475# echo 0 >value
root@salvator-x:/sys/class/gpio/gpio475# echo "in" > direction
root@salvator-x:/sys/class/gpio/gpio475# echo "out" > direction
  来控制输出输入  ,电平高低 。
  最后,关于 Pinctrl 的内容还有太多要写,就先写到这把。。。。。
  来不及写 参考文档了,具体是 结合 wowotech 和 公司的设备,要下班了。。。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-408106-1-1.html 上篇帖子: 20179223《Linux内核原理与解析》第六周学习笔记 下篇帖子: 20179223《Linux内核原理与分析》第五周学习笔记
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表