嵌入式Linux之使用设备树驱动GPIO的实现方式

嵌入式Linux设备树驱动GPIO实现

1. 设备树节点配置

在设备树文件中添加设备节点描述:

gpio-device {
    compatible = "custom-gpio-driver";
    gpios = <&gpio0 12 0>,  // 使用GPIO0组第12脚
            <&gpio1 3 1>;   // 使用GPIO1组第3脚,高电平有效
    led-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
};

关键参数说明:

  • gpio0:SOC内置GPIO控制器节点
  • 数字编号:引脚序号
  • 标志位:指定有效电平状态
2. 驱动实现关键函数
#include <linux/gpio/consumer.h>

struct gpio_desc *gpio;
int value;

// 获取GPIO资源
gpio = gpiod_get(dev, "led", 0); 

// 配置为输出模式
gpiod_direction_output(gpio, 0);

// 设置电平状态
gpiod_set_value(gpio, 1);

// 读取输入状态
value = gpiod_get_value(gpio);

// 释放资源
gpiod_put(gpio);
3. 完整驱动框架示例
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>

struct custom_gpio_data {
    struct gpio_desc *led_pin;
};

static int gpio_probe(struct platform_device *pdev)
{
    struct custom_gpio_data *data;
    
    data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
    
    data->led_pin = gpiod_get(&pdev->dev, "led", GPIOD_OUT_LOW);
    if (IS_ERR(data->led_pin)) {
        dev_err(&pdev->dev, "无法获取GPIO\n");
        return PTR_ERR(data->led_pin);
    }
    
    // 设置初始电平
    gpiod_set_value(data->led_pin, 1);
    
    platform_set_drvdata(pdev, data);
    return 0;
}

static const struct of_device_id gpio_dt_ids[] = {
    { .compatible = "custom-gpio-driver" },
    {}
};
MODULE_DEVICE_TABLE(of, gpio_dt_ids);

static struct platform_driver gpio_driver = {
    .driver = {
        .name = "custom-gpio",
        .of_match_table = gpio_dt_ids,
    },
    .probe = gpio_probe,
};

module_platform_driver(gpio_driver);
4. 验证流程
  1. 编译设备树:
    dtc -I dts -O dtb -o myboard.dtb myboard.dts
    
  2. 加载设备树:
    fdtput /boot/myboard.dtb /gpio-device status "okay"
    
  3. 查看GPIO状态:
    cat /sys/kernel/debug/gpio
    
  4. 用户空间测试:
    echo 1 > /sys/class/gpio/gpio12/value
    
5. 注意事项
  • 引脚复用配置需正确设置pinctrl
  • 注意GPIO电气特性配置(上拉/下拉)
  • 多个GPIO操作需考虑并发控制
  • 使用gpiod_*系列API替代已废弃的gpio_*函数

数学关系表示:
当配置GPIO方向时,存在状态关系:
方向模式 = { 0 输入模式 1 输出模式 \text{方向模式} = \begin{cases} 0 & \text{输入模式} \\ 1 & \text{输出模式} \end{cases} 方向模式={01输入模式输出模式

电平状态满足:
V o u t = { V D D 当 value = 1 0 V 当 value = 0 V_{out} = \begin{cases} V_{DD} & \text{当} \quad \text{value} = 1 \\ 0V & \text{当} \quad \text{value} = 0 \end{cases} Vout={VDD0Vvalue=1value=0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷爱码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值