尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
ShiMetaPi-Pico-G1:外设与接口(1)
1. GPIO子系统在 Linux 系统中GPIO 由专门的 GPIO 子系统统一管理该子系统基于内核的 GPIO 框架gpiolib实现为 GPIO 硬件提供标准化的抽象接口。通过该框架内核能够对不同平台的 GPIO 控制器进行统一封装使用户空间或内核驱动可以以一致的方式访问 GPIO 资源。 GPIO的控制方式有两种通过sysfs文件系统导出到用户空间进行控制从而以文件读写的方式实现对 GPIO 引脚的操作。(旧GPIO接口路径在 /sys/class/gpio/,现在 Linux 内核已经不推荐继续使用)使用基于字符设备的 GPIO 接口gpiochip。(新GPIO接口路径在/dev/gpiochipN,Linux 官方推荐的新方式)GPIO编号计算每组GPIO有8个GPIO管脚GPIO编号等于GPIO组合\*8组内偏移号例如GPIO4_2的GPIO编号为 4\*8234 使用字符设备驱动时GPIO1_4chip_path对应/dev/gpiochip1,line_offset对应42. character GPIO2.1 专业术语libgpiodlibgpiod 是 Linux 用户空间访问 GPIO通用输入输出的标准库是现代 GPIO 子系统gpiolib character device interface的官方用户态接口。ioctlioctl 是一种设备控制系统调用接口用于在 read/write 之外通过命令码request和结构化参数arg与设备驱动进行交互实现设备配置、状态查询和特殊控制功能。说明libgpiod 是 Linux 官方提供的 GPIO 用户空间参考库它对 GPIO character device ioctl 接口进行了封装提供统一的 GPIO line 申请、控制与事件 API。它在功能上相当于 GPIO 的用户态抽象层userspace abstraction layer但本质上仍依赖 ioctl 与内核 gpiolib 交互。同时用户完全可以绕过 libgpiod直接基于 ioctl 实现自己的 GPIO 抽象层。2.2 GPIO ioctl的使用2.2.1 头文件linux/gpio.h这个头文件里定义了常用结构体和 ioctlstruct gpiohandle_requeststruct gpiohandle_datastruct gpioevent_request以及这些 ioctl 命令GPIO_GET_CHIPINFO_IOCTLGPIO_GET_LINEINFO_IOCTLGPIO_GET_LINEHANDLE_IOCTLGPIO_GET_LINEEVENT_IOCTLGPIOHANDLE_GET_LINE_VALUES_IOCTLGPIOHANDLE_SET_LINE_VALUES_IOCTL2.2.2 相关结构体gpiohandle_request用于申请普通输入/输出 GPIO line。关键成员lineoffsets[]line 编号flags输入还是输出default_values[]默认输出值consumer_label给内核看的占用者名字fd成功后返回 line 句柄gpiohandle_data用于读写 line 电平。关键成员values[]每条 line 的值gpioevent_request用于申请中断事件 line。关键成员lineoffsetline 编号handleflags通常输入eventflags上升沿/下降沿/双边沿fd成功后返回事件 fd2.3 实现呼吸灯应用程序参考快速入门/部署第一个应用程序创建并编写gpio_hal.c#include gpio_hal.h #include errno.h #include fcntl.h #include stdio.h #include string.h #include sys/ioctl.h #include unistd.h int gpio_handle_init(gpio_handle_t *gpio_handle) { struct gpiohandle_request req; if (gpio_handle NULL || gpio_handle-chip_path NULL) { errno EINVAL; return -1; } gpio_handle-chip_fd -1; gpio_handle-line_fd -1; gpio_handle-chip_fd open(gpio_handle-chip_path, O_RDONLY); if (gpio_handle-chip_fd 0) { perror(open gpiochip); return -1; } memset(req, 0, sizeof(req)); req.lineoffsets[0] gpio_handle-line_offset; req.flags gpio_handle-gpio_mode; req.default_values[0] gpio_handle-default_value ? 1 : 0; req.lines 1; if (gpio_handle-consumer_label[0] ! \0) { strncpy(req.consumer_label, gpio_handle-consumer_label, sizeof(req.consumer_label) - 1); req.consumer_label[sizeof(req.consumer_label) - 1] \0; } else { strncpy(req.consumer_label, gpio-led, sizeof(req.consumer_label) - 1); req.consumer_label[sizeof(req.consumer_label) - 1] \0; } if (ioctl(gpio_handle-chip_fd, GPIO_GET_LINEHANDLE_IOCTL, req) 0) { perror(GPIO_GET_LINEHANDLE_IOCTL); close(gpio_handle-chip_fd); gpio_handle-chip_fd -1; return -1; } gpio_handle-line_fd req.fd; return 0; } int gpio_set_value(gpio_handle_t *gpio_handle, int value) { struct gpiohandle_data data; if (gpio_handle NULL || gpio_handle-line_fd 0) { errno EINVAL; return -1; } memset(data, 0, sizeof(data)); data.values[0] value ? 1 : 0; if (ioctl(gpio_handle-line_fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, data) 0) { perror(GPIOHANDLE_SET_LINE_VALUES_IOCTL); return -1; } return 0; } void gpio_handle_close(gpio_handle_t *gpio_handle) { if (gpio_handle NULL) return; if (gpio_handle-line_fd 0) { close(gpio_handle-line_fd); gpio_handle-line_fd -1; } if (gpio_handle-chip_fd 0) { close(gpio_handle-chip_fd); gpio_handle-chip_fd -1; } }创建并编写gpio_hal.h#ifndef GPIO_HAL_H #define GPIO_HAL_H #ifdef __cplusplus extern C { #endif #include linux/gpio.h #define GPIO_CONSUMER_LABEL_LEN 32 typedef struct gpio_handle_t { int chip_fd; const char *chip_path; unsigned int line_offset; unsigned int gpio_mode; int default_value; int line_fd; char consumer_label[GPIO_CONSUMER_LABEL_LEN]; } gpio_handle_t; int gpio_handle_init(gpio_handle_t *gpio_handle); int gpio_set_value(gpio_handle_t *gpio_handle, int value); void gpio_handle_close(gpio_handle_t *gpio_handle); #ifdef __cplusplus } #endif #endif创建并编写main.c#include gpio_hal.h #include linux/gpio.h #include stdio.h #include string.h #include unistd.h #define LED_CHIP_PATH /dev/gpiochip1 #define LED_LINE 6 int main(void) { gpio_handle_t led_handle; memset(led_handle, 0, sizeof(led_handle)); led_handle.chip_path LED_CHIP_PATH; led_handle.line_offset LED_LINE; led_handle.gpio_mode GPIOHANDLE_REQUEST_OUTPUT; led_handle.default_value 0; snprintf(led_handle.consumer_label, sizeof(led_handle.consumer_label), led-gpio); if (gpio_handle_init(led_handle) 0) { perror(gpio_handle_init); return 1; } printf(LED GPIO set high\n); if (gpio_set_value(led_handle, 1) 0) { gpio_handle_close(led_handle); return 1; } sleep(5); printf(LED GPIO set low\n); if (gpio_set_value(led_handle, 0) 0) { gpio_handle_close(led_handle); return 1; } gpio_handle_close(led_handle); return 0; }创建并编写MakefileSDK_DIR : $(shell cd $(shell pwd)/../../.. /bin/pwd) include $(SDK_DIR)/build/base.mk TARGET : gpio SRCS : main.c gpio_hal.c OBJS : $(SRCS:.c.o) .PHONY: all clean install all: $(TARGET) $(TARGET): $(OBJS) $(CC) $(SDK_LD_CFLAGS) -o $ $^ %.o: %.c $(CC) $(SDK_USR_CFLAGS) -c -o $ $ install: all mkdir -p $(XMEDIA_ROOTFS_DIR)/usr/bin cp -f $(TARGET) $(XMEDIA_ROOTFS_DIR)/usr/bin/$(TARGET) chmod 755 $(XMEDIA_ROOTFS_DIR)/usr/bin/$(TARGET) echo Installed $(TARGET) to $(XMEDIA_ROOTFS_DIR)/usr/bin/$(TARGET) clean: rm -f $(TARGET) $(OBJS)将应用程序编译进rootfs文件系统登录Pico-G1运行应用程序预期结果LED亮5秒后熄灭3 使用sysfs控制GPIO3.1 将GPIO导出到用户空间在板端 /sys/class/gpio 目录中每个 GPIO 设备都有其自己的文件夹。这些文件夹的名称是 gpio 加上引脚编号例如 /sys/class/gpio/gpio14 表示引脚编号为 14 的引脚即 GPIO1_6。用户可使用如下命令查看~ # echo 14 /sys/class/gpio/export ~ # ls /sys/class/gpio/ export gpiochip0 gpiochip24 gpiochip40 gpiochip56 gpiochip8 gpio14 gpiochip16 gpiochip32 gpiochip48 gpiochip64 unexport说明echo 14 sys/class/gpio 表示把 GPIO14 导出到用户空间,导出后就会生成/sys/class/gpio/gpio14 可以使用 echo 14 /sys/class/gpio/unexport 命令取消导出3.2 GPIO控制目录导出的GPIO对应的控制目录(即/sys/class/gpio/gpio14)里通常会有这些文件:~ # ls /sys/class/gpio/gpio14/ active_low direction power uevent device edge subsystem valueactive_low用于设置 GPIO 电平逻辑是否反向 示例echo 1 /sys/class/gpio/gpio14/active_low # 表示把GPIO14 的电平逻辑设置为反向direction用于设置 GPIO 的方向也就是它是输入还是输出 示例echo in /sys/class/gpio/gpio14/direction #输入 echo out /sys/class/gpio/gpio14/direction #输出power电源管理相关目录/文件一般不直接操作。uevent和设备事件相关通常不是用户日常手工控制 GPIO 时最常用的文件device表示这个 GPIO 所属的设备信息edgeecho both /sys/class/gpio/gpio14/edge配置中断触发边沿常见值none不产生中断rising上升沿触发中断falling下降沿触发中断both双边沿触发中断subsystem表示这个 GPIO 属于哪个子系统value用于读取或设置GPIO的电平值cat /sys/class/gpio/gpio14/value #读取电平echo 1 /sys/class/gpio/gpio14/value #设置为高电平 echo 0 /sys/class/gpio/gpio14/value #设置为低电平
RELATED

相关推荐

VMnet8 IP分配失败的真相:NAT与DHCP服务协同机制解析

VMnet8 IP分配失败的真相:NAT与DHCP服务协同机制解析

1. 项目概述:VMnet8不是“坏了”,而是它的服务逻辑被误解了“VMnet8无法分配有效IP地址”——这句话在VMware用户群、技术论坛和企业IT支持工单里出现频率之高,几乎可以排进虚拟化故障TOP3。但绝大多数人一看到这个报错,第一反应是…

📅 2026/10/1 10:02:56
Sunshine 游戏串流怎么配?PC 游戏免费串到电视的完整新手指南

Sunshine 游戏串流怎么配?PC 游戏免费串到电视的完整新手指南

Sunshine 游戏串流怎么配?PC 游戏免费串到电视的完整新手指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine 是一个开源、自托管的游戏串流服务器&#xff0…

📅 2026/10/1 9:57:56
具身智能协同演化动力学(57):协同演化体系提高长时序连续自主作业能力

具身智能协同演化动力学(57):协同演化体系提高长时序连续自主作业能力

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”)是依托Transformer架构与“因式智能体”理论构建的新型工业视觉系统,也是当前最具代表性的具身视觉技术之一。它有机融合深度强化学习&…

📅 2026/10/1 9:57:56
MORE NEWS

更多资讯

📰

Python爬虫实战:从豆瓣短评到中文词云生成保姆级教程

前两天帮朋友处理了一个小需求:把一部电影在豆瓣上的最新短评爬下来,生成一张词云图看看观众都在聊什么。当时顺手写了个Python脚本,从requests爬评论,到jieba分词,再到wordcloud生成词云,前后加起来不到两…

📰

Vue + Electron 入门:从主进程IPC通信到打包避坑指南

Vue Electron 开发入门教程 如果你是一个Web前端开发者,想用自己熟悉的Vue技术栈做一款桌面应用,Electron几乎是最省事的路径。不用学新的UI框架,不用重新啃原生API,HTML、CSS、JavaScript 那套理论直接搬过来,再加上…

📰

前端Web组态软件选型实战:图元、协议、渲染与国产化深度解析

1. 为什么前端 Web 组态软件正在成为工业数字化落地的关键支点最近半年,我连续参与了三个中型制造企业的可视化监控平台升级项目,从最初被要求“做个大屏看数据”,到客户主动提出“要能拖拽改画面、连PLC不用写代码、运维人员自己就能调参数”…

📰

HER强化学习目标重标记:破解稀疏奖励难题的实用指南

1. 先搞清楚 hindsight 到底在解决什么问题 先别急着看代码,我需要先讲清楚为什么会有 hindsight 这个东西。如果你是刚接触强化学习不久的读者,大概率遇到过这种场景:写了个 DDPG 或者 PPO,在 Gym 的拿物体、推箱子这类任务上训练…

📰

连续时间傅里叶变换直觉指南:从波形到频谱的工程思维

这一章题目看着是教科书里的标准章节,但“连续时间傅里叶变换”这东西,恰恰是我见过最容易“背了一堆公式却不知道在干嘛”的内容。当年我学到这里,变换对、性质、收敛条件背得滚瓜烂熟,考试也没问题。直到工作后参与一个音频处理…

📰

普通显卡可训练的自研神经网络Waver-SNN-SSM

1. 项目概述:为什么一个“普通显卡可训练”的自研神经网络值得认真对待 “个人开源自研神经网络!普通显卡可训练!!”——这个标题乍看像极了技术社区里常见的流量型口号,但拆开来看,每个词都踩在当下AI开发…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬