Live2d Test Env

pinctrl&gpio介绍

  目的: 实现IO口功能设置的软硬件分离

  pinctrl:通过设备树节点,记录不同板级硬件信息; Pinctrl 遵循的是platform 框架实现实现设备总线。

  gpio:   通过一些列的API接口,读取设备树中pinctrl节点的硬件信息,设置相应的引脚功能。

 

pinctrl文件位置:

  Linux文件结构的drivers/pinctrl文件夹下,有不同公司的pinctrl文件 ,以STM为例:

  pinctrl中的信息分两类:{

    控制文件 pinctrl32-stm32.c  pinctrl-stm32.h 

    板级信息描述文件:如 pinctrl-stm32mp157.c  文件主要记录了IO信息,并注册到platform总线的接口 stm32mp157_pinctrl_init    

  }  

                                

  pinctrl-stm32mp157.c 文件介绍:

    结构体介绍:

        stm32_desc_pin  管脚信息记录结构体

        stm32_pinctrl_match_data  节点描述记录,将管脚信息集合,

        of_device_id   根据 compatible 信息与设备树中的compatible 进行匹配,查询引脚的硬件信息

        platform_driver   注册到 platform 总线上。

    接口介绍:

      stm32mp157_pinctrl_init 将 stm32mp157_pinctrl_driver (platform_driver类型) 挂载到platform总线上

      每个 IO 信息记录表:方便在IO复用时进行查询对照;该文件分两个结构体数组进行记录:stm32mp157_pins(stm32_desc_pin)、stm32mp157_z_pins(stm32_desc_pin  )

      信息表汇成一个集合:stm32mp157_pctrl_match ( of_device_id)

 

 

设备树pinctrl 信息描述:

   公共基础信息: stm32mp151.dtsi 中记录了pinctrl节点,包含了所有IO的端口复用信息(每个端口都能有哪些复用功能),compatible信息等

  功能信息节点描述:stm32mp15-pinctrl.dtsi 描述了每个功能时,都哪些管脚可以进行复用设置。(pinctrl控制节点,加入pinctrl总线)同时可以自定义添加要使用的控制节点。

  上面两个都是设备厂商描述好的。

  应用时设置(设备树节点)         stm32mp157d-atk.dts 这个文件是实际应用是添加的一个设备树文件,在 / 跟节点下创建要使用的节点,在该节点中描述要使用的IO复用信息.

  eg:

//添加一个led节点
gpioled {  //可以通过节点名称获取这个节点的信息
 compatible = "alientek,led";  //通过compatible 信息总线可以进行match匹配设备和驱动
 led-gpio = <&gpioi 0 GPIO_ACTIVE_LOW>;  //设置端口PI0 为GPIO功能 默认低电平  led-gpio 这个名称可以进行端口设置
 status = "okay";
 };

 

gpio系统:

  对驱动层提供了一套关于IO引脚操作的API函数。

int gpio_request(unsigned gpio, const char *label)//label 是给这个GPIO 重新设置个名称
void gpio_free(unsigned gpio)
int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio, int value)
//获取某个 GPIO 的值(0 或 1),此函数是个宏
#define gpio_get_value __gpio_get_value
int __gpio_get_value(unsigned gpio)
//设置某个 GPIO 的值,此函数是个宏,定义如
#define gpio_set_value __gpio_set_value
void __gpio_set_value(unsigned gpio, int value)

  与gpio相关of 函数,读取设备树信息

/*获取设备树某个属性里面定义了几个 GPIO 信息,要注意的
是空的 GPIO 信息也会被统计到*/
int of_gpio_named_count(struct device_node *np, const char *propname)
//统计gpio这个属性的IO数量
int of_gpio_count(struct device_node *np)

/*获取 GPIO 编号*/
int of_get_named_gpio(struct device_node *np,const char *propname,int index)


//eg  设备树信息参考上面的设置
/*获取设备节点,设备树中的节点名称是 gpioled*/
gpioled.nd = of_find_node_by_path("/gpioled");
/*获取设备树中的 gpio 属性,得到 LED 所使用的 LED 编号  led-gpio 这个名称是设备树中IO信息设置名称*/
gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "led-gpio", 0);
/*申请 gpioled.led_gpio 这个节点的IO口为 GPIO*/
ret = gpio_request(gpioled.led_gpio, "LED-GPIO");
/*设置这个节点的IO口为输出方向*/
ret = gpio_direction_output(gpioled.led_gpio, 1);

 

 流程梳理:
  1. stm32mp15-pinctrl.dtsi  &pinctrl 中设置相应的节点,添加 pin 属性

  2. 设备树中添加设备节点,这个节点会记录到IO的设置;/proc/device-tree 下会出现相应的设备树节点信息。

  3. 通过of_gpio相关函数读取设备树的信息。

 

    

 

posted @ 2024-07-25 15:51  爬上那个坡  阅读(7)  评论(0编辑  收藏  举报