- Navigation (`・ω・´)
- house主页
- 作品
- 暮光小猿图片管理器2
- av_timerSC 科学创造
- 记录
- videocam没事瞎折腾系列
- devices隔壁老王210
- devicesLinux嵌入式
- 关于
- archive更新日志
- restore历史版本
哔哩哔哩 - ( ゜- ゜)つロ 乾杯~
实验环境
- 硬件: Orange PI Zero 512M
- CPU: Allwiner H2+
- 内核版本: 3.4.113
- 操作系统: Armbian 版本忘了
OrangePi zero 引脚图
(图片来自网络)
命令行控制GPIO
先来看一下用脚本(或命令行)是怎么控制GPIO的
#!/bin/bash
# 命令行Bash脚本控制GPIO输出
# 测试控制PA1
# 检查是否已经导出
if [ ! -e /sys/class/gpio/gpio1 ]
then
# 没有导出,导出1号GPIO
echo 1 > /sys/class/gpio/export
fi
# 设置为输出
echo out > /sys/class/gpio/gpio1/direction
# PA1开关3次
for i in {1..3}
do
# 设置高电平
echo high > /sys/class/gpio/gpio1/direction
sleep 0.2
# 设置低电平
echo low > /sys/class/gpio/gpio1/direction
sleep 0.2
done
# 释放PA1
echo 1 > /sys/class/gpio/unexport
GPIO 编号
上面使用PA1时 使用的编号是1 这个1的来源...
先不管后面数字 先说PA PB PC...
PA=0*32=0, PB=1*32=32, PC=2*32=64, 一组是32个(虽然实际上一组并没有32个)
然后再加上编号就可以了
举个栗子: PA0=0*32+0=0, PA9=0*32+9=9, PB3=1*32+3=35, PC4=2*32+4=68...
提个问题: PL10的编号是多少?
[查看答案]
查看GPIO占用
有些GPIO已经被其它程序占用, 如红色STATUS-LED的PA17
可以通过 /sys/kernel/debug/gpio 文件查看已经分配的GPIO
root@orangepizero:~/gpioTest# cat /sys/kernel/debug/gpio
GPIOs 0-383, platform/sunxi-pinctrl, sunxi-pinctrl:
gpio-10 (gpiotest ) out hi
gpio-17 (red_led ) out lo
gpio-69 (? ) out hi
gpio-202 (xradio_irq ) in lo
gpio-354 (? ) out hi
gpio-362 (green_led ) out hi
但这也不代表这些已经分配的就不能再用了! (下一篇解释)
内核模块控制GPIO
终于到正片了..
跟以前一样复制好Makefile, 在C文件里定义好入口出口函数
东西不多, 直接上整个文件
gpio.c
#include <linux/module.h>
#include <asm/gpio.h> // GPIO头文件
// 用10号(PA10)作例子
static int gpio = 10;
static int __init gpio_m_init(void)
{
// 申请10号 (等于上面的 echo 10 > export)
int result = gpio_request(gpio, "gpiotest");
if (result == 0) {
printk(KERN_INFO "GPIO request ok\n");
} else {
printk(KERN_ERR "GPIO request err\n");
return -1;
}
// 设置为输出, 输出0(低电平) (等于上面的 echo out > gpio10/direction)
gpio_direction_output(gpio, 0);
// 设置为高电平 (为了演示 上一条指令可以直接设置输出高) (等于上面的 echo high > gpio10/direction)
gpio_set_value(gpio, 1);
return 0;
}
static void __exit gpio_m_exit(void)
{
// 输出低电平 (等于上面的 echo low > gpio10/direction)
gpio_set_value(gpio, 0);
// 释放 (等于上面的 echo 10 > unexport)
gpio_free(gpio);
}
module_init(gpio_m_init);
module_exit(gpio_m_exit);
MODULE_LICENSE("GPL");
Makefile
# 前边都用过了 就不再解释了 试着自己理解内容
NAME = GPIO_Test
KDIR := /usr/src/linux-headers-3.4.113-sun8i
obj-m := $(NAME).o
$(NAME)-objs := gpio.o
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
-rm -rf *.ko *.o *.symvers modules.order $(NAME).*
load:
insmod $(NAME).ko
unload:
rmmod $(NAME)
测试
根据页面开头的GPIO图 找到PA10和GND
选用PA10就是因为它好找
编译并加载模块 PA10就会输出高电平(3.3v)
root@orangepizero:~/gpioTest# make
make -C /usr/src/linux-headers-3.4.113-sun8i M=/root/gpioTest modules
make[1]: Entering directory '/usr/src/linux-headers-3.4.113-sun8i'
CC [M] /root/gpioTest/gpio.o
LD [M] /root/gpioTest/GPIO_Test.o
Building modules, stage 2.
MODPOST 1 modules
CC /root/gpioTest/GPIO_Test.mod.o
LD [M] /root/gpioTest/GPIO_Test.ko
make[1]: Leaving directory '/usr/src/linux-headers-3.4.113-sun8i'
root@orangepizero:~/gpioTest# make load
insmod GPIO_Test.ko
GPIO分配里也能查到被这个模块占用了
root@orangepizero:~/gpioTest# cat /sys/kernel/debug/gpio
GPIOs 0-383, platform/sunxi-pinctrl, sunxi-pinctrl:
gpio-10 (gpiotest ) out hi
gpio-17 (red_led ) out lo
gpio-69 (? ) out hi
gpio-202 (xradio_irq ) in lo
gpio-354 (? ) out hi
gpio-362 (green_led ) out hi
卸载模块 PA10变回低电平(0v)
root@orangepizero:~/gpioTest# make unload
rmmod GPIO_Test