https://blog.csdn.net/qq_41076734/article/details/124669908
1. 应用空间控制gpio
1.1简介
在/sys/class/gpio/下有个export文件,向export文件写入要操作的GPIO号,使得该GPIO的操作接口从内核空间暴露到用户空间,GPIO的操作接口包括direction和value等,direction控制GPIO输入或者输出模式,而value可控制GPIO的状态或者读取状态。
/sys/class/gpio/目录下各个文件说明:
/sys/class/gpio/export文件用于通知系统需要导出控制的GPIO引脚编号;
/sys/class/gpio/unexport 用于通知系统取消导出;
/sys/class/gpio/gpioX/direction文件,可以写入in(设置输入方向)或out(设置输出方向);
/sys/class/gpio/gpioX/value文件是可以读写GPIO状态;
/sys/class/gpio/gpiochipX目录保存系统中GPIO寄存器的信息,包括每个寄存器控制引脚的起始编号,寄存器名称,引脚总数;其中X表示具体的引脚编号。
如果你在sys/class/gpio/下面没有看到gpioX,可能是这个 GPIO 管脚还没有被导出(export)供用户态使用,如下图:
你可以试试以下步骤:
- 执行
echo <GPIO_Number> > /sys/class/gpio/export
导出 GPIO 管脚,将GPIO_Number
替换为你想操作的 GPIO 编号。 - 检查
/sys/class/gpio/gpio<GPIO_Number>
(将GPIO_Number
替换为你想操作的 GPIO 编号)目录下是否有direction
和value
文件。
需要导出的GPIO编号(GPIO Number)往往取决于具体的硬件设计和应用需求。每个GPIO口在硬件设计图(如原理图)中通常都有对应的编号,这个就是GPIO的物理编号。而在编程中使用的GPIO编号则取决于操作系统和驱动如何映射这些物理GPIO口。在许多情况下,硬件设计师或者系统集成者会提供一个文档,列出了各个GPIO口的物理编号和它们的功能(比如连接到哪个设备、控制什么信号等)。在这个文档的帮助下,你可以确定你在应用程序中需要使用哪个GPIO口,然后查找相应的GPIO编号。
在某些情况下,你可能需要查看内核源代码或者硬件抽象层(HAL)的源代码来找出物理GPIO口和GPIO编号之间的映射关系。
1.2操作gpio
比如我要操作GPIO8_A6作为高电平输出有效, 那么有以下三个操作:
1. 2.1 换算对应的gpio number
可以通过/sys/kernel/debug/gpio查询信息:
root@rk3288:/sys/kernel/debug # cat gpio
//snip
GPIOs 184-215, platform/ff770000.pinctrl, gpio6:
gpio-193(?) in hi
gpio-194(?) in hi
GPIOs 216-247, platform/ff770000.pinctrl, gpio7:
gpio-218(enable ) out hi
gpio-219(lcd_en ) in hi
gpio-220(lcd_cs ) in hi
gpio-221(gslX680 wake pin ) out hi
gpio-222(gslX680 irq pin ) out lo
gpio-223(headset_gpio ) in hi
gpio-233(?) in hi
gpio-234(?) in hi
GPIOs 248-279, platform/ff770000.pinctrl, gpio8:
GPIOs 280-311, platform/ff770000.pinctrl, gpio15:
可以看到gpio8是以nubmer为248开始, 那么GPIO8_A6就是 248 + 6 = 254,接下来就可以导出gpio了。
root@rk3288:/sys/class/gpio # echo 254> export
root@rk3288:/sys/class/gpio # ls
export
gpio254
1.2.2 设置成输出
root@rk3288:/sys/class/gpio/gpio254 # echo out > direction
root@rk3288:/sys/class/gpio/gpio254 # cat direction
out
1.2.3 输出高电平
root@rk3288:/sys/class/gpio/gpio254 # echo 1> value
root@rk3288:/sys/class/gpio/gpio254 # cat value
1.3 总结
这种方式一般不采用,为了gpio使用的安全性,一般是不将gpio的使用权暴露给应用层的,即sys/class/下没有gpio节点。
2. 内核空间控制gpio
在内核空间控制gpio有两种方法,第一种是通过调用gpiolib的接口来控制gpio;第二种是通过ioremap来控制gpio。
2.1 gpiolib控制gpio
2.1.1 gpiolib简介
Linux Kernel 中对 GPIO 资源进行了抽象,抽象出一个叫做 Gpiolib 的东西。
2.1.2 Gpiolib 为其他驱动提供的 APIs
intgpio_request(unsigned gpio,constchar*label);/*向内核申请 gpio,要使用 GPIO 首先应该向内核进行申请,返回 0,代表申请成功,
*可以进行后续操作*/voidgpio_free(unsigned gpio);/*对应 gpio_request,是使用完gpio以后把gpio释放掉*/intgpio_direction_input(unsigned gpio);/*设置 GPIO 为输入*/intgpio_direction_output(unsigned gpio,int value);/*设置 GPIO 为输出*/intgpio_get_value(unsigned gpio);/*读取 GPIO 的值*/intgpio_set_value(unsigned gpio);/*设置 GPIO 的值*/
2.1.3 操作gpio
功能和1.2一样。
#defineGPIO8_A6254
ret =gpio_request(GPIO8_A6 ,"gpio8_a6");if(!ret){printk("request for gpio8_a6 failed:%d\n", ret);return0;}gpio_direction_output(GPIO8_A6 ,1);//设置GPIO8_A6为输出功能且输出高电平
2.2 ioremap控制gpio
这种方法会降低程序的可读性,不建议使用。
linux内核空间访问的地址为虚拟地址(3~4GB),故在内核空间操作某个寄存器时,需先通过ioremap函数将物理地址映射成虚拟地址。
用ioremap() 获取寄存器的地址:
unsignedint __iomem *base_addr1;//__iomem可选择,告诉你为虚拟地址#defineGPIO8_REGBASE(0x20A0000)#defineGPIO8_A6(*(volatileunsignedint*)(base_addr1 +6))//指针unsigned int为4字节,指针加1,字节加4
base_addr1 =ioremap(GPIO8_REGBASE,0x14)
通过 readl() 或者 writel() 函数直接操作映射后的地址:
GPIO8_A6 |=(1<<8);int temp;
temp =readl(GPIO8_A6);
temp |=(1<<8);writel(temp, GPIO8_A6);
使用完后,取消映射:
iounmap(base_addr1);
3. 查看GPIO全部信息
cat /sys/kernel/debug/pinctrl/pinctrl/pinmux-pins
Pinmux settings per pin
Format:pin(name): mux_owner gpio_owner hog?
pin 0(gpio0-0): wireless-wlan(GPIO UNCLAIMED) function wireless-wlan group wifi-wake-host
pin 1(gpio0-1):(MUX UNCLAIMED)(GPIO UNCLAIMED)
pin 2(gpio0-2):(MUX UNCLAIMED) gpio0:2
pin 3(gpio0-3):(MUX UNCLAIMED)(GPIO UNCLAIMED)
pin 4(gpio0-4):(MUX UNCLAIMED)(GPIO UNCLAIMED)
pin 5(gpio0-5):(MUX UNCLAIMED) gpio0:5
pin 6(gpio0-6):(MUX UNCLAIMED)(GPIO UNCLAIMED)
pin 7(gpio0-7):(MUX UNCLAIMED) gpio0:7
pin 8(gpio0-8):(MUX UNCLAIMED)(GPIO UNCLAIMED)
pin 9(gpio0-9):(MUX UNCLAIMED)(GPIO UNCLAIMED)
pin 10(gpio0-10):(MUX UNCLAIMED)(GPIO UNCLAIMED)
pin 11(gpio0-11): ff050000.i2c(GPIO UNCLAIMED) function i2c1 group i2c1-xfer
pin 12(gpio0-12): ff050000.i2c(GPIO UNCLAIMED) function i2c1 group i2c1-xfer
pin 13(gpio0-13):(MUX UNCLAIMED)(GPIO UNCLAIMED)
版权归原作者 Twinkle544 所有, 如有侵权,请联系我们删除。