/sys/class/gpio 文件接口操作IO端口

本文详细介绍了Linux系统下GPIO操作的通用接口sysfs,包括如何使用/sys/class/gpio文件夹导出控制GPIO引脚,设置输入输出方向及控制GPIO电平状态。以2440平台为例,提供了从GPIO信息获取、导出引脚、配置方向到实际LED控制的完整流程。

在嵌入式设备中对GPIO的操作是最基本的操作。一般的做法是写一个单独驱动程序,网上大多数的例子都是这样的。其实linux下面有一个通用的GPIO操作接口,那就是我要介绍的 “/sys/class/gpio” 方式。

首先,看看系统中有没有“/sys/class/gpio”这个文件夹。如果没有请在编译内核的时候加入   Device Drivers  —>  GPIO Support  —>     /sys/class/gpio/… (sysfs interface)。

/sys/class/gpio 的使用说明:

01 gpio_operation 通过/sys/文件接口操作IO端口 GPIO到文件系统的映射
02 * 控制GPIO的目录位于/sys/class/gpio
03 * /sys/class/gpio/export文件用于通知系统需要导出控制的GPIO引脚编号
04 * /sys/class/gpio/unexport 用于通知系统取消导出
05 * /sys/class/gpio/gpiochipX目录保存系统中GPIO寄存器的信息,包括每个寄存器控制引脚的起始编号base,寄存器名称,引脚总数 导出一个引脚的操作步骤
06 * 首先计算此引脚编号,引脚编号 = 控制引脚的寄存器基数 + 控制引脚寄存器位数
07 * 向/sys/class/gpio/export写入此编号,比如12号引脚,在shell中可以通过以下命令实现,命令成功后生成/sys/class/gpio/gpio12目录,如果没有出现相应的目录,说明此引脚不可导出:
08 echo 12 > /sys/class/gpio/export
09 * direction文件,定义输入输入方向,可以通过下面命令定义为输出
10 echo out > direction
11 * direction接受的参数:in, out, high, low。high/low同时设置方向为输出,并将value设置为相应的1/0。
12 * value文件是端口的数值,为1或0.
13 echo 1 > value

下面在2440下进行一下测试

1.取得GPIO信息,在终端中敲入以下命令

1 $ cd /sys/class/gpio
2 for i in gpiochip* ; do echo `cat $i/label`: `cat $i/base` ; done

终端中显示如下

1 GPIOA: 0
2 GPIOE: 128
3 GPIOF: 160
4 GPIOG: 192
5 GPIOH: 224
6 GPIOB: 32
7 GPIOC: 64
8 GPIOD: 96

2.计算GPIO号码

我们把GPE11用来控制LED。

GPE0的头是128,GPE11 就是128+11 = 139.

1 $ echo 139 >; /sys/class/gpio/export

ls 一下看看有没有 gpio139 这个目录

3.GPIO控制测试。

控制LED所以是输出。

所以我们应该执行

1 $ echo out > /sys/class/gpio/gpio139/direction

之后就可以进行输出设置了。

1 $ echo 1 > /sys/class/gpio/gpio139/value

or

1 $ echo 0 > /sys/class/gpio/gpio139/value
<think> 我们讨论的是一个内核模块(.ko文件)的用途。根据路径和模块名称: 路径: ./output/luofu_ax3000_lite_release/rootfs/lib/modules/5.10.0/gpio-dwapb.ko 模块名: gpio-dwapb 这个内核模块是用于支持特定GPIO控制器的驱动程序。 具体来说: - "gpio" 表示这是一个GPIO(通用输入输出)控制器驱动。 - "dwapb" 代表的是"DesignWare APB GPIO"。 因此,gpio-dwapb.ko 是用于支持DesignWare公司的基于APB(Advanced Peripheral Bus)总线的GPIO控制器的内核模块。 功能: 1. 提供对DesignWare APB GPIO控制器的驱动支持。 2. 允许系统通过Linux的标准GPIO接口操作这些GPIO引脚。 3. 支持多个GPIO端口(banks)和中断功能。 适用场景: 该驱动通常用在集成了DesignWare APB GPIO控制器的SoC系统中,比如一些基于ARM的嵌入式设备。 在代码中的体现: 该模块在内核中注册为一个平台驱动(platform driver),与设备树中的兼容节点匹配(例如兼容字符串为"snps,dw-apb-gpio")。 以下是一个简化的代码结构示例(基于Linux内核源码): ```c #include <linux/platform_device.h> #include <linux/gpio/driver.h> #include <linux/module.h> // 设备树匹配表 static const struct of_device_id dwapb_of_match[] = { { .compatible = "snps,dw-apb-gpio" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, dwapb_of_match); // 探测函数 static int dwapb_gpio_probe(struct platform_device *pdev) { // 1. 从设备树获取资源(内存、中断等) // 2. 初始化GPIO控制器 // 3. 注册GPIO控制器 return devm_gpiochip_add_data(&pdev->dev, &chip, NULL); } // 移除函数 static int dwapb_gpio_remove(struct platform_device *pdev) { // 移除GPIO控制器 return 0; } // 定义平台驱动结构 static struct platform_driver dwapb_gpio_driver = { .driver = { .name = "gpio-dwapb", .of_match_table = dwapb_of_match, }, .probe = dwapb_gpio_probe, .remove = dwapb_gpio_remove, }; module_platform_driver(dwapb_gpio_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Some Author"); MODULE_DESCRIPTION("Driver for DesignWare APB GPIO"); ``` 该驱动的主要作用是将硬件上的GPIO控制器抽象为Linux的GPIO控制器,这样用户空间可以通过sysfs接口(/sys/class/gpio)或者libgpio库来操作GPIO。 因此,在你的系统中,这个ko文件(内核模块)是用来驱动某个硬件上的DesignWare APB GPIO控制器的。 §§相关问题§§: 1. 如何在Linux内核中注册一个GPIO控制器? 2. 设备树(Device Tree)在Linux驱动中扮演什么角色? 3. 用户空间如何通过sysfs操作GPIO? 4. 内核模块的加载和卸载函数分别有什么作用? </think> ### `gpio-dwapb.ko` 内核模块详解 #### 模块功能与作用: `gpio-dwapb.ko` 是 Linux 内核中用于 **DesignWare APB GPIO 控制器**的硬件驱动程序模块。其主要功能是为基于 Synopsys DesignWare IP 的 GPIO 控制器提供硬件抽象层支持。 核心功能包括: 1. 管理 GPIO 引脚的输入/输出配置 2. 实现 GPIO 中断处理 3. 提供 GPIO 状态监控 4. 支持多组 GPIO 控制器并行操作 #### 典型应用场景: 1. ARM SoC 系统(如 NXP i.MX、Intel SoC FPGA) 2. 嵌入式设备 GPIO 控制 3. 工业控制设备 4. 物联网网关设备 5. 路由器/交换机控制面板管理 #### 代码实现解析: 以下是该驱动核心功能的简化实现(基于 Linux 5.10 内核源码): ```c #include <linux/platform_device.h> #include <linux/gpio/driver.h> #include <linux/module.h> /* 设备树匹配表 */ static const struct of_device_id dwapb_of_match[] = { { .compatible = "snps,dw-apb-gpio" }, // 设备树兼容标识 { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, dwapb_of_match); /* GPIO 控制器操作函数 */ static const struct gpio_chip dwapb_gpio_chip = { .direction_input = dwapb_gpio_direction_input, .direction_output = dwapb_gpio_direction_output, .get = dwapb_gpio_get_value, .set = dwapb_gpio_set_value, .to_irq = dwapb_gpio_to_irq, .base = -1, // 动态分配基数 .ngpio = 32, // 每控制器GPIO数量 .can_sleep = false, }; /* 中断处理函数 */ static irqreturn_t dwapb_irq_handler(int irq, void *dev_id) { struct dwapb_gpio *gpio = dev_id; unsigned long irq_status; // 读取中断状态寄存器 irq_status = dwapb_read(gpio, GPIO_INTSTATUS); // 处理每个GPIO中断 for_each_set_bit(bit, &irq_status, gpio->nr_gpio) { int child_irq = irq_find_mapping(gpio->domain, bit); handle_nested_irq(child_irq); } return IRQ_HANDLED; } /* 设备探测函数 */ static int dwapb_gpio_probe(struct platform_device *pdev) { struct dwapb_gpio *gpio; int err; // 分配控制器内存 gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); // 映射寄存器地址 gpio->regs = devm_platform_ioremap_resource(pdev, 0); // 初始化GPIO控制器 err = bgpio_init(&gpio->gc, &pdev->dev, 4, gpio->regs + GPIO_EXT_PORTA, gpio->regs + GPIO_SWPORTA_DR, NULL, gpio->regs + GPIO_SWPORTA_DDR, NULL, 0); // 注册GPIO控制器 err = devm_gpiochip_add_data(&pdev->dev, &gpio->gc, gpio); // 中断处理配置 if (gpio->irq >= 0) { err = devm_request_irq(&pdev->dev, gpio->irq, dwapb_irq_handler, IRQF_SHARED, "dwapb-gpio", gpio); } return 0; } /* 平台驱动定义 */ static struct platform_driver dwapb_gpio_driver = { .driver = { .name = "gpio-dwapb", .of_match_table = dwapb_of_match, }, .probe = dwapb_gpio_probe, }; module_platform_driver(dwapb_gpio_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Synopsys DesignWare APB GPIO driver"); ``` #### 关键功能实现: 1. **GPIO 控制**: - `dwapb_gpio_direction_input()`:配置GPIO为输入模式 - `dwapb_gpio_direction_output()`:配置GPIO为输出模式 - `dwapb_gpio_get_value()`:读取GPIO当前状态 - `dwapb_gpio_set_value()`:设置GPIO输出值 2. **中断处理**: - 支持边沿/电平触发中断 - 多GPIO共享中断处理 - 中断状态寄存器轮询 3. **设备树集成**: ```dts // 典型设备树节点 gpio0: gpio@f0000000 { compatible = "snps,dw-apb-gpio"; reg = <0xf0000000 0x1000>; #address-cells = <1>; #size-cells = <0>; porta: gpio-port@0 { compatible = "snps,dw-apb-gpio-port"; gpio-controller; #gpio-cells = <2>; snps,nr-gpios = <32>; }; }; ``` #### 模块应用示例: ```c #include <linux/gpio/consumer.h> // 用户驱动中使用GPIO struct gpio_desc *led_gpio; probe_function() { // 获取GPIO led_gpio = gpiod_get(dev, "led", GPIOD_OUT_LOW); // 控制GPIO gpiod_set_value(led_gpio, 1); // 打开LED } interrupt_handler() { if (gpiod_get_value(button_gpio)) { gpiod_set_value(led_gpio, 0); // 按钮按下时关闭LED } } ``` #### 模块参数配置: 加载时可配置参数: ```bash insmod gpio-dwapb.ko dwapb_irq_priority=2 # 中断优先级 dwapb_gpio_debounce=2000 # 去抖动时间(us) dwapb_ngpio=64 # GPIO数量 ``` #### 调试技巧: 1. 监控GPIO状态: ```bash watch -n 0.5 'cat /sys/kernel/debug/gpio' ``` 2. 触发GPIO中断测试: ```c // 强制触发中断 iowrite32(0xFF, gpio->regs + GPIO_INTMASK); ``` --- ### 总结: 1. **功能**:提供 DesignWare APB GPIO 控制器的硬件抽象 2. **层级**:Linux GPIO 子系统下的平台驱动 3. **依赖**:需要设备树配合配置硬件参数 4. **接口**:通过 `/sys/class/gpio` 和 GPIO 子系统 API 暴露功能 5. **重要性**:在嵌入式系统中实现硬件控制的关键组件
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值