首页
商城
  • English
  • 简体中文
首页
商城
  • English
  • 简体中文
  • 产品系列

    • FPGA+ARM

      • GM-3568JHF

        • 一、简介

          • GM-3568JHF 简介
        • 二、快速开始

          • 00 前言
          • 01 环境搭建
          • 02 编译说明
          • 03 烧录指南
          • 04 调试工具
          • 05 软件更新
          • 06 查看信息
          • 07 测试命令
          • 08 应用编译
          • 09 源码获取
        • 三、外设与接口

          • 01 USB
          • 02 显示与触摸
          • 03 以太网
          • 04 WIFI
          • 05 蓝牙
          • 06 TF-Card
          • 07 音频
          • 08 串口
          • 09 CAN
          • 10 RTC
        • 四、应用开发

          • 01 UART读写案例
          • 02 按键检测案例
          • 03 LED灯闪烁案例
          • 04 MIPI屏幕检测案例
          • 05 读取 USB 设备信息案例
          • 06 FAN 检测案例
          • 07 FPGA FSPI 通信案例
          • 08 FPGA DMA 读写案例
          • 09 GPS调试案例
          • 10 以太网测试案例
          • 11 RS485读写案例
          • 12 FPGA IIC 读写案例
          • 13 PN532 NFC读卡案例
          • 14 TF卡读写案例
        • 五、QT开发

          • 01 ARM64交叉编译器环境搭建
          • 02 QT 程序加入开机自启服务
        • 六、RKNN_NPU开发

          • 01 RK3568 NPU 概述
          • 02 开发环境搭建
          • 运行官方 YOLOv5 示例
        • 七、FPGA开发

          • ARM与FPGA通讯
          • FPGA开发手册
        • 八、其他

          • 01 根目录文件系统的修改
          • 02 系统自启服务
        • 九、资料下载

          • 资料下载
    • ShimetaPi

      • M4-R1

        • 一、简介

          • M4-R1简介
        • 二、快速上手

          • 01 OpenHarmony概述
          • 02 镜像烧录
          • 03 应用开发快速上手
          • 04 设备开发快速上手
        • 三、应用开发

          • 01 ArkUI

            • 1 ArkTS语言简介
            • 2 UI 组件-Row 容器介绍
            • 3 UI 组件-Column 容器介绍
            • 4 UI 组件-Text 组件
            • 5 UI 组件-Toggle 组件
            • 6 UI 组件-Slider 组件
            • 7 UI 组件-Animation 组件&Transition 组件
          • 02 资料获取

            • 1 OpenHarmony 官方资料
          • 03 开发须知

            • 1 Full-SDK替换教程
            • 2 引入和使用三方库
            • 3 HDC调试
            • 4 命令行恢复出厂模式
            • 5 升级App为system权限
          • 04 构建第一个应用

            • 1 构建第一个ArkTs应用-HelloWorld
          • 05 案例

            • 01 串口调试助手应用案例
            • 02 手写板应用案例
            • 03 数字时钟应用案例
            • 04 WIFI 信息获取应用案例
        • 四、设备开发

          • 1 Ubuntu环境开发

            • 01 环境搭建
            • 02 下载源码
            • 03 编译源码
          • 2 使用DevEco Device Tool 工具

            • 01 工具简介
            • 02 开发环境的搭建
            • 03 导入SDK
            • 04 HUAWEI DevEco Tool 功能介绍
        • 五、内核外设与接口

          • 01 指南
          • 02 设备树介绍
          • 03 NAPI 入门
          • 04 ArkTS入门
          • 05 NAPI开发实战演示
          • 06 GPIO介绍
          • 07 I2C通讯
          • 08 SPI通信
          • 09 PWM 控制
          • 10 串口通讯
          • 11 TF卡
          • 12 屏幕
          • 13 触摸
          • 14 Ethernet(以太网)
          • 15 M.2 硬盘
          • 16 音频
          • 17 WIFI & BT
          • 18 摄像头
        • 六、资料下载

          • 资料下载
      • M5-R1

        • 一、简介

          • M5-R1 开发文档
        • 二、快速上手

          • 镜像烧录
          • 环境搭建
          • 下载源码
        • 三、外设与接口

          • 树莓派接口
          • GPIO 接口
          • I2C 接口
          • SPI通信
          • PWM控制
          • 串口通讯
          • TF Card
          • 屏幕
          • 触摸
          • 音频
          • RTC
          • Ethernet
          • M.2
          • MINI-PCIE
          • Camera
          • WIFI&BT
        • 四、资料下载

          • 资料下载
      • Pico-G1

        • 一、产品概述

          • 01 芯片与硬件平台介绍
          • 02 SDK版本说明
        • 二、快速入门

          • 01 开发环境搭建
          • 02 镜像编译
          • 03 镜像烧录
          • 04 系统登录
          • 05 网络配置
          • 06 文件传输
          • 07 SDK目录结构
          • 08 部署第一个应用程序
          • 09 部署第一个驱动程序
          • 10 SD卡挂载
        • 三、外设与接口

          • 01 GPIO控制
          • 02 UART串口通信
          • 03 I2C 通信
          • 04 SPI 通信
        • 四、MPP媒体开发

          • 01 MPP媒体处理软件
          • 02 图像处理链路
          • 03 视频输入
          • 04 图像编码
        • 五、NPU与AI

          • 01 NPU驱动与运行库架构
          • 02 .xmm 模型加载
          • 03 SVP视频处理
          • 04 AI降噪 (AI_NR)
        • 六、应用程序示例

          • 01 区域运动检测应用
          • 02 MTCNN 人脸检测应用
    • 开源鸿蒙

      • SC-3568HA

        • 一、简介

          • SC-3568HA简介
        • 二、快速上手

          • OpenHarmony概述
          • 镜像烧录
          • 开发环境准备
          • Hello World应用以及部署
        • 三、应用开发

          • ArkUI

            • 第一章 ArkTS语言简介
            • 第二章 UI组件介绍和实际应用(上)
            • 第三章 UI组件介绍和实际应用(中)
            • 第四章 UI组件介绍和实际应用(下)
          • 拓展

            • 第一章 入门指引
            • 第二章 三方库的引用和使用
            • 第三章 应用编译以及部署
            • 第四章 命令行恢复出厂设置
            • 第五章 系统调试--HDC调试
            • 第六章 APP 稳定性测试
            • 第七章 应用测试
        • 四、设备开发

          • 第一章 环境搭建
          • 第二章 下载源码
          • 第三章 编译源码
        • 五、内核的外设与接口

          • 树莓派接口
          • GPIO 接口
          • I2C 接口
          • SPI通信
          • PWM控制
          • 串口通讯
          • TF Card
          • 屏幕
          • 触摸
          • 音频
          • RTC
          • Ethernet
          • M.2
          • MINI-PCIE
          • Camera
          • WIFI&BT
          • 树莓派拓展板
        • 六、资料下载

          • 资料下载
      • M-K1HSE

        • 一、简介

          • M-K1HSE 简介
        • 二、快速开始

          • 开发环境搭建
          • 源码获取
          • 编译说明
          • 烧录指南
        • 三、应用开发

          • 00 应用开发环境搭建
          • 01 第一个应用-Hello World
        • 四、外设与接口

          • 01 Audio
          • 02 RS485
          • 03 Display
        • 五、系统定制开发

          • 系统移植
          • 系统定制
          • 驱动开发
          • 系统调试
          • OTA升级
        • 六、资料下载

          • 资料下载
    • EVS相机

      • CF-NRS1

        • 一、简介

          • 01-产品介绍
          • 02-相关概念
          • 03-MultiVision Studio 介绍
        • 二、开发

          • 01-ShiMetaPi Hybrid vision SDK 介绍
          • 02-Hybrid_vision_toolkit
          • 03-Hybrid_vision_toolkit API (C++)
          • 04 Hybrid Vision algo
          • 05 Hybrid vision algo API
          • 06 EVS Network Server
          • 07 EVS Time Sync
          • 08 Web Window
        • 三、资料下载

          • 资料下载
        • 四、常见问题

          • 常见问题解决指南
      • CF-CRA2

        • 一、简介

          • CF-NRS2 简介
        • 二、资料下载

          • 资料下载
      • EVS模块

        • 一、相关概念
        • 二、硬件准备与环境配置
        • 三、示例程序使用指南
        • 资料下载
    • AI硬件

      • 1684XB-32T

        • 一、简介

          • AIBOX-1684XB-32简介
        • 二、快速上手

          • 初次使用
          • 网络配置
          • 磁盘使用
          • 内存分配
          • 风扇策略
          • 固件升级
          • 交叉编译
          • 模型量化
        • 三、应用开发

          • 开发简介

            • Sophgo SDK开发
            • SOPHON-DEMO简介
          • 大语言模型

            • 部署Llama3示例
            • Sophon LLM_api_server开发
            • 部署MiniCPM-V-2_6
            • Qwen-2-5-VL图片视频识别DEMO
            • Qwen3-chat-DEMO
            • Qwen3-Qwen Agent-MCP开发
            • Qwen3-langchain-AI Agent
          • 深度学习

            • ResNet(图像分类)
            • LPRNet(车牌识别)
            • SAM(通用图像分割基础模型)
            • YOLOv5(目标检测)
            • OpenPose(人体关键点检测)
            • PP-OCR(光学字符识别)
        • 四、资料下载

          • 资料下载
      • 1684X-416T

        • 简介

          • AIBOX-1684X-416简介
        • Demo简单操作指引

          • shimeta智慧监控demo的简单使用说明
      • RDK-X5

        • 简介

          • RDK-X5 硬件简介
        • 快速开始

          • RDK-X5 快速开始
        • 应用开发

          • AI在线模型开发

            • 实验01-接入火山引擎豆包 AI
            • 实验02-图片分析
            • 实验03-多模态视觉分析定位
            • 实验04-多模态图文比较分析
            • 实验05-多模态文档表格分析
            • 实验06-摄像头运用-AI视觉分析
          • 大语言模型

            • 实验01-语音识别
            • 实验02-语音对话
            • 实验03-多模态图片分析-语音对话
            • 实验04-多模态图片比较-语音对话
            • 实验05-多模态文档分析-语音对话
            • 实验06-多模态视觉运用-语音对话
          • ROS2基础开发

            • 实验01-搭建环境
            • 实验02-工作包的创建及编译
            • 实验03-运行 ROS2 话题通信节点
            • 实验04-ROS2 相机应用
          • 40pin-IO开发

            • 实验01-GPIO 输出(LED闪烁)
            • 实验02-GPIO 输入
            • 实验03-按键控制 LED
            • 实验04-PWM 输出
            • 实验05-串口输出
            • 实验06-IIC 实验
            • 实验07-SPI 实验
          • USB模块开发使用

            • 实验01-USB 语音模块使用
            • 实验02-声源定位模块使用
          • 机器视觉技术实战

            • 实验01-打开 USB 摄像头
            • 实验02-颜色识别检测
            • 实验03-手势识别体验
            • 实验04-YOLOv5物体检测
      • RDK-S100

        • 简介

          • RDK-S100 硬件简介
        • 快速开始

          • RDK-S100 硬件简介
        • 应用开发

          • AI在线模型开发

            • 实验01-接入火山引擎豆包 AI
            • 实验02-图片分析
            • 实验03-多模态视觉分析定位
            • 实验04-多模态图文比较分析
            • 实验05-多模态文档表格分析
            • 实验06-摄像头运用-AI视觉分析
          • 大语言模型

            • 实验01-语音识别
            • 实验02-语音对话
            • 实验03-多模态图片分析-语音对话
            • 实验04-多模态图片比较-语音对话
            • 实验05-多模态文档分析-语音对话
            • 实验06-多模态视觉运用-语音对话
          • ROS2基础开发

            • 实验01-搭建环境
            • 实验02-工作包的创建及编译
            • 实验03-运行 ROS2 话题通信节点
            • 实验04-ROS2 相机应用
          • 40pin-IO开发

            • 实验01-GPIO 输出(LED闪烁)
            • 实验02-GPIO 输入
            • 实验03-按键控制 LED
            • 实验04-PWM 输出
            • 实验05-串口输出
            • 实验06-IIC 实验
            • 实验07-SPI 实验
          • USB模块开发使用

            • 实验01-USB 语音模块使用
            • 实验02-声源定位模块使用
          • 机器视觉技术实战

            • 实验01-打开 USB 摄像头
            • 实验02-图像处理基础
            • 实验03-目标检测
            • 实验04-图像分割
    • 核心板

      • C-3568BQ

        • 简介

          • C-3568BQ 简介
      • C-3588LQ

        • 简介

          • C-3588LQ 简介
      • GC-3568JBAF

        • 简介

          • GC-3568JBAF 简介
      • C-K1BA

        • 简介

          • C-K1BA 简介

01 GPIO控制

1. GPIO子系统

在 Linux 系统中,GPIO 由专门的 GPIO 子系统统一管理,该子系统基于内核的 GPIO 框架(gpiolib)实现,为 GPIO 硬件提供标准化的抽象接口。通过该框架,内核能够对不同平台的 GPIO 控制器进行统一封装,使用户空间或内核驱动可以以一致的方式访问 GPIO 资源。 GPIO的控制方式有两种:

  1. 通过sysfs文件系统导出到用户空间进行控制,从而以文件读写的方式实现对 GPIO 引脚的操作。(旧GPIO接口,路径在 /sys/class/gpio/,现在 Linux 内核已经不推荐继续使用)
  2. 使用基于字符设备的 GPIO 接口(gpiochip)。(新GPIO接口,路径在/dev/gpiochipN,Linux 官方推荐的新方式)

引脚分布

GPIO编号计算

每组GPIO有8个GPIO管脚,GPIO编号等于GPIO组合\*8+组内偏移号,例如GPIO4_2的GPIO编号为 4\*8+2=34 使用字符设备驱动时,GPIO1_4:chip_path对应/dev/gpiochip1,line_offset对应4

2. character GPIO

2.1 专业术语

  • libgpiod

    libgpiod 是 Linux 用户空间访问 GPIO(通用输入输出)的标准库,是现代 GPIO 子系统(gpiolib character device interface)的官方用户态接口。

  • ioctl

    ioctl 是一种设备控制系统调用接口,用于在 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

这个头文件里定义了常用结构体和 ioctl:

  • struct gpiohandle_request
  • struct gpiohandle_data
  • struct gpioevent_request

以及这些 ioctl 命令:

  • GPIO_GET_CHIPINFO_IOCTL
  • GPIO_GET_LINEINFO_IOCTL
  • GPIO_GET_LINEHANDLE_IOCTL
  • GPIO_GET_LINEEVENT_IOCTL
  • GPIOHANDLE_GET_LINE_VALUES_IOCTL
  • GPIOHANDLE_SET_LINE_VALUES_IOCTL

2.2.2 相关结构体

gpiohandle_request

用于申请普通输入/输出 GPIO line。

关键成员:

  • lineoffsets[]:line 编号
  • flags:输入还是输出
  • default_values[]:默认输出值
  • consumer_label:给内核看的占用者名字
  • fd:成功后返回 line 句柄

gpiohandle_data

用于读写 line 电平。

关键成员:

  • values[]:每条 line 的值

gpioevent_request

用于申请中断事件 line。

关键成员:

  • lineoffset:line 编号
  • handleflags:通常输入
  • eventflags:上升沿/下降沿/双边沿
  • fd:成功后返回事件 fd

2.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;
}

创建并编写Makefile

SDK_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秒后熄灭

注意

若未能达到预期效果,可能是LED所在GPIO被复用为其他功能,可执行以下指令

xmmd.l 0x11980018 #查看GPIO1_6寄存器的值
xmmm 0x11980018 0x00001000 #修改寄存器的值

修改后可继续运行应用程序

3 使用sysfs控制GPIO

3.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   value

active_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 所属的设备信息

edge

echo both > /sys/class/gpio/gpio14/edge

配置中断触发边沿,常见值:

  1. none:不产生中断
  2. rising:上升沿触发中断
  3. falling:下降沿触发中断
  4. 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	#设置为低电平
在 GitHub 上编辑此页
上次更新:
贡献者: ljh
Next
02 UART串口通信