Linux子系统之GPIO

本文详细介绍了Linux内核中的GPIO子系统,包括其层次结构、API接口,并提供了通过设备树配置和控制GPIO的具体实例,还对比了传统的GPIO操作方法与新引入的gpiod子系统的不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.GPIO子系统

1.1GPIO子系统的层次结构

在这里插入图片描述

1.2GPIO子系统的API接口

int of_get_named_gpio(struct device_node *np,const char *propname, int index)
功能:根据节点结构体解析gpio编号
参数:
    @np:节点指针
	@propname:键
    @index:索引号
返回值:成功返回gpio的编号,失败返回错误码

int gpio_request(unsigned gpio, const char *label)
功能:申请要使用的gpio
参数:
    @gpio:gpio的编号
    @label:标签名
返回值:成功返回0,失败返回错误码

int gpio_direction_input(unsigned gpio)
功能:设置gpio的为输入
参数:
    @gpio:gpio的编号
返回值:成功返回0,失败返回错误码
        
int gpio_direction_output(unsigned gpio, int value)
功能:设置gpio的为输出
参数:
    @gpio:gpio的编号
    @value:默认电平的状态 1高电平  0低电平
返回值:成功返回0,失败返回错误码
 
int gpio_get_value(unsigned gpio)
功能:读取管脚的值
参数:
    @gpio:gpio的编号
返回值:1高电平  0低电平
        
void gpio_set_value(unsigned gpio, int value)    
功能:设置输出电平的值
参数:
     @gpio:gpio的编号
	 @value:1高电平  0低电平
返回值:无

void gpio_free(unsigned gpio)
功能:释放gpio
参数:
     @gpio:gpio的编号
返回值:无    

1.3GPIO子系统的设备树添加

1.3.1LED的硬件原理图

在这里插入图片描述

注:控制器的设备树在Linux内核源码中已经写好了

1.3.2控制器的设备树

//stm32mp151.dtsi
  pinctrl: pin-controller@50002000 {
   
    #address-cells = <1>; //子节点地址的个数
    #size-cells = <1>;   //子节点地址长度的个数
    gpioe: gpio@50006000 {
   
        gpio-controller;  //空属性,只起到标识作用
        #gpio-cells = <2>;  //修饰子节点成员的个数
        reg = <0x50006000 0x400>;//描述地址
        clocks = <&rcc GPIOE>;   //时钟
        st,bank-name = "GPIOE";                                                         
        status = "disabled";   //控制器的状态,disabled:控制器没有工作,okay:工作
    };
 }&pinctrl {
   
        gpioe: gpio@50006000 {
   
        status = "okay";  //使能控制器
        ngpios = <16>;    //这一组管脚的个数
        gpio-ranges = <&pinctrl 0 64 16>; //管脚的排序
    };                                                                                          
}

1.3.3编写自己的设备树

参考内核帮助文档填写自己的设备树。

/home/linux/linux-5.10.61/Documentation/devicetree/bindings/gpio/gpio.txt

myleds{
   
    led1 = <&gpioe 10 0>;
    led2 = <&gpiof 10 0>;
    led3 = <&gpioe 8 0>;
};

1.4GPIO子系统点灯的实例

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
// myleds{
   
//     led1 = <&gpioe 10 0>;
//     led2 = <&gpiof 10 0>;
//     led3 = <&gpioe 8 0>;
// };
struct device_node* node;
char* pname[] = {
    "led1", "led2", "led3" };
int gpiono[3] = {
    0 };
static int __init myleds_init(void)
{
   
    int i, ret;
    // 1.获取device_node
    node = of_find_node_by_name(NULL, "myleds");
    if (node == NULL) {
   
        printk("parse device node error\n");
        return -ENODATA;
    }
    // 2.获取gpio编号
    for (i = 0; i < ARRAY_SIZE(gpiono); i++) {
   
        gpiono[i] = of_get_named_gpio(node, pname[i], 0);
        if (gpiono[i] < 0) {
   
            printk("get gpio number error\n");
            return -EINVAL;
        }
        // 3.申请要使用的gpio
        if ((ret = gpio_request(gpiono[i], NULL)) != 0) {
   
            printk("reqeust gpio error");
            return ret;
        }
        // 4.操作gpio
        gpio_direction_output(gpiono[i], 1);
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值