我是靠谱客的博主 受伤树叶,这篇文章主要介绍GPIO+Pinctrl,现在分享给大家,希望可以做个参考。

文章目录

          • 子系统(驱动和硬件之间又加了一个环节)
          • GPIO子系统
          • Pinctrl子系统(解决IO复用管理的问题)一般都是搭配GPIO子系统

子系统(驱动和硬件之间又加了一个环节)
  • 所谓子系统就是将一类驱动进行规范化,提供统一的接口,这样驱动开发者不需要去实现底层的重复驱动代码,而是将重点放到设备驱动程序本身
  • 所谓子系统就是将共有的东西抽象为一个统一框架,提供上层统一的接口,而底层由每个厂家自己实现,这样驱动层去调用这些底层接口的时候就不需要考虑底层的实现,而只需要使用统一的API即可。
    在这里插入图片描述在这里插入图片描述
  • 上述linux驱动程序需要依靠linux子系统的接口API,而linux子系统又要依靠bsp驱动程序的API
    公司代码会分配至少两个部分,驱动程序和BSP驱动程序(与硬件(设备寄存器与总线信息)紧密相关,其中dtb的编写也是bsp开发人员的任务)
GPIO子系统

步骤:
(1)申请GPIO资源

static inline int devm_gpio_request(struct device *dev,
										 unsigned gpio, 
									  const char *label) 

(2)申请完资源后我们需要设置GPIO方向

static inline int gpio_direction_input(unsigned gpio)
static inline int gpio_direction_output(unsigned gpio, int value)

(3)获取和设置GPIO的值

#define gpio_get_value __gpio_get_value
static inline int __gpio_get_value(unsigned gpio)
#define gpio_set_value __gpio_set_value
static inline void __gpio_set_value(unsigned gpio, int value)

(4)释放GPIO资源

static inline void devm_gpio_free(struct device *dev, unsigned int gpio)

当引入设备树之后
所有的设备信息一般都需要先从设备树中获取,下面函数用于从设备树中获取 GPIO 编号:

static inline int of_get_named_gpio(struct device_node *np,//设备节点
										const char *propname,//gpio属性名称 
										int index)//gpio属性名称的索引

GPIO与中断信号线
在linux中,GPIO引脚也可以作为中断信号线,即对于gpio控制器而言其也可以是一个中断控制器。通常我们利用一个GPIO当作一个中断信号线,例如外部触发信号。

Gpio转为中断信号线函数:

#define gpio_to_irq __gpio_to_irq
static inline int __gpio_to_irq(unsigned gpio)
//这样去实现一个按键,
int key_irq = gpio_to_irq(KEY_IRQ_PIN);

由于目前驱动开发都结合设备树来开发,所以上面的子系统接口API都已经丢弃使用,

在新的 GPIO 子系统中,所有的操作函数都是 gpiod 为前缀
步骤:

(1)从设备树中获取GPIO的描述信息

struct gpio_desc *__must_check gpiod_get( struct device *dev,//设备结构体
const char *con_id,//gpio属性id名字
enum gpiod_flags flags)//gpio输入输出状态标记
struct gpio_desc *__must_check devm_gpiod_get( struct device *dev,
												 const char *con_id,
												 enum gpiod_flags flags)

(2)申请完资源后我们需要设置GPIO方向

int gpiod_direction_input(struct gpio_desc *desc)
int gpiod_direction_output(struct gpio_desc *desc, int value)

(3)获取和设置GPIO输出电平

int gpiod_get_value(const struct gpio_desc *desc)
void gpiod_set_value(struct gpio_desc *desc, int value)

(4)释放GPIO资源

void gpiod_put(struct gpio_desc *desc)
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)

GPIO与中断信号线

int gpiod_to_irq(const struct gpio_desc *desc)
Pinctrl子系统(解决IO复用管理的问题)一般都是搭配GPIO子系统

在这里插入图片描述
节点分析

  • Compatible用于匹配pinctrl子系统的底层驱动程序
  • Reg指定该GPIO控制器的寄存器映射地址
  • Interrupts指定该GPIO控制器的中断信号线
  • Clocks属性指定pintrl时钟的主时钟源,clocks-names属性对clocks进行了说明
  • Gpio-controller属性表明该节点是一个控制器
  • #gpio-cells属性了在引用GPIO节点时需要有三个单元
  • #interrupt-cells属性指定了引用该节点作为中断时需要有的三个单元
    上述为pinctrl设备树节点,该设备树节点用于给 pinctrl子系统记录 GPIO 的寄存器和 GPIO 引脚的复用功能。

映射复用功能:
由于pinctrl子系统是管理GPIO引脚复用的,因此在将GPIO映射为其它功能时,我们需要在 pinctrl设备树节点中添加我们的功能比如:们需要使用串口 uart0 功能,那么 uart一定是复 用了两个 GPIO 引脚,
在这里插入图片描述
设备树节点引用复用功能:
在这里插入图片描述
上述设备节点出现了
pinctrl-0 = <&uart0_pins>属性,指定pin的状态功能,若作普通引脚pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default"属性,指定其ID名称

步骤:
(1)设备树添加我们的LED设备节点
(2)为了能够方便调试,使用sysfs设备文件系统驱动框架,这样就不要写测试APP了
(3)使用paltform驱动框架
(4)编译模块.ko调试(sysfs虚拟文件系统下)

最后

以上就是受伤树叶最近收集整理的关于GPIO+Pinctrl的全部内容,更多相关GPIO+Pinctrl内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(119)

评论列表共有 0 条评论

立即
投稿
返回
顶部