惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy International News Feed
Hacker News - Newest:
Hacker News - Newest: "LLM"
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
Google Online Security Blog
Google Online Security Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Stack Overflow Blog
Stack Overflow Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
P
Proofpoint News Feed
A
Arctic Wolf
Forbes - Security
Forbes - Security
Spread Privacy
Spread Privacy
Security Latest
Security Latest
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
AWS News Blog
AWS News Blog
M
MIT News - Artificial intelligence
GbyAI
GbyAI
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
Help Net Security
Help Net Security
博客园 - Franky
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
S
Schneier on Security
S
SegmentFault 最新的问题
Microsoft Security Blog
Microsoft Security Blog
Y
Y Combinator Blog
PCI Perspectives
PCI Perspectives
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Palo Alto Networks Blog
SecWiki News
SecWiki News
TaoSecurity Blog
TaoSecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
Kaspersky official blog
G
Google Developers Blog
H
Hacker News: Front Page
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
T
Troy Hunt's Blog
F
Full Disclosure
T
Threat Research - Cisco Blogs

博客园 - 靖意风

使用QT 将可执行程序 进行打包 对使用的屏幕的整理 对mmc 设备进行分区 开发板启动时间优化 nmcli 设置网络配置 虚拟机下 安装 ubuntu 18.04 硬件基础知识__串口 字节对齐问题和 小端格式 在ubuntu下 编译23位的测试文件 31_了解 x6818开发板是 如何使用/dev/ttySAC0 进行打印log 10_linux dirver platform 框架 ubuntu24.04.02 下安装软件 记录 ubuntu 更新源 vmware 虚拟机的三种网卡 vmware 安装 ubuntu 24.04.02 07_linux 字符设备了解 04_kernel编程框架和 printk传参 03_uboot 命令整理 01_stm32 裸板程序 01_了解嵌入式开发
05_使用linux内核的gpio库函数
靖意风 · 2025-05-30 · via 博客园 - 靖意风

1. 回顾ARM裸板GPIO输出开关灯操作代码:

//四选一:选择为GPIO功能
GPIOCALTFN0 &= ~(3 << 24);
GPIOCALTFN0 |= (1 << 24);

//二选一:选择为输出功能
GPIOCOUTENB |= (1 << 12);

//输出1或者0
GPIOCOUT |= (1 << 12);
GPIOCOUT &= ~(1 << 12);

缺点:此代码可读性非常差劲,还必须研究手册,然后做位运算
办法:在linux内核中,内核提供了相关的GPIO操作函数,可以直接使用,从而简化GPIO操作的流程

2. 内核提供的GPIO操作函数

2.1.int gpio_request(unsigned gpio, const char *label)
功能:在linux内核中,处理器的任何GPIO硬件对于linux内核来说
都是一种宝贵的资源,内核程序要想访问操作某个GPIO
硬件,必须利用此函数先向内核申请这个GPIO资源
类似:malloc
参数:
gpio:在linux内核中,内核给每个GPIO硬件都指定分配唯一的一个
软件编号,简称GPIO编号,类似GPIO硬件的身份证号
GPIO硬件对应的软件编号定义:
例如:
GPIO硬件 GPIO编号
GPIOC12 PAD_GPIO_C + 12
GPIOB26 PAD_GPIO_B + 26
... ...
label:随意指定一个标签名称即可,表示申请的GPIO硬件的标识
返回值:不用记,只需参考内核代码如何使用判断此函数的返回值即可

2.2.void gpio_free(unsigned gpio)
功能:如果内核程序不再使用某个GPIO硬件,记得要释放资源

2.3.gpio_direction_output(unsigned gpio, int value);
功能:配置GPIO为输出功能同时输出value(1高/0低)

2.4.gpio_direction_input(unsigned gpio);
功能:配置GPIO为输入功能

2.5.gpio_set_value(unsigned gpio, int value);
设置GPIO的输出值为value(1/0)
此函数使用的前提是提前配置为输出功能

2.6.int gpio_get_value(unsigned gpio);
获取GPIO的电平状态,返回值保存状态
此函数对输入还是输出无要求

3. 编写代码和测试

// led.c
#include <linux/init.h>
#include <linux/module.h>
#include <mach/platform.h> // 定义PAD_GPIO_C 等宏
#include <linux/gpio.h>

struct led_resource {
    char *name;
    int gpio;
};

static struct led_resource led_info[] = {
    {
        .name = "led1",
        .gpio = PAD_GPIO_C + 12
    },
    {
        .name = "led4",
        .gpio = PAD_GPIO_B + 26
    }
};

static int led_init(void) {
    int i;
    for (i = 0; i < ARRAY_SIZE(led_info); i++) {
        gpio_request(led_info[i].gpio, led_info[i].name);
        gpio_direction_output(led_info[i].gpio, 0);
        printk("%s: 打开第%d个灯\n", __func__,  i+1);
    }

    return 0;
}

static void led_exit(void) {
    int i;
    for (i = 0; i < ARRAY_SIZE(led_info); i++) {
        gpio_set_value(led_info[i].gpio, 1);
        gpio_free(led_info[i].gpio);
        printk("%s: 关闭第%d个灯\n", __FUNCTION__, i);
    }
}

module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
obj-m += led.o
all:
    make -C /opt/kernel SUBDIRS=$(PWD) modules
clean:
    make -C /opt/kernel SUBDIRS=$(PWD) clean

// 开发板的测试结果

/home/driver # insmod led.ko 
[ 7411.801000] led_init: 打开第1个灯
[ 7411.801000] led_init: 打开第2个灯
/home/driver # 
/home/driver # rmmod led
[ 7415.065000] led_exit: 关闭第0个灯
[ 7415.065000] led_exit: 关闭第1个灯
/home/driver #