上周helloworld成功跑起来了,这周来整一下GPIO,说到GPIO那就必须得是经典的点亮一个LED灯。
但是从单片机转到linux,想点个灯就没有那么简单了,在单片机中就直接配置寄存器,如果用STM32的直接在cubemx中图形化配置,完成外设的初始化,然后调用对应控制GPIO的函数即可。但是在linux中就没有那么简单了,所以我找了半天的资料,最终兜兜转转还是回到了ST的wiki, 不得不说,ST在资料方面做的真是不错,像我这样没有原厂FEA支持的开发者,也可以通过公开释放的资料,进行学习开发,当然ST也有论坛,不过我没有去提问过。好了言归正传,开始今日的点灯
首先我把对应的wiki连接放这里(https://wiki.stmicroelectronics.cn/stm32mpu/wiki/Overview_of_GPIO_pins),这一页简单介绍了135关于引脚配置和控制的Linux内核框架,如下图所示
从图中我们可以看到,135的引脚控制只有3个,irqchip、pinctrl、GPIOlib。其中irqchip听名字就知道是管中断的,不在今天点灯的范畴里,我就不看了。另外两个都可以管GPIO,但是他俩各有特点,我就直接把ST的原文借过来了
可以使用两个框架来配置和控制给定的引脚:pinctrl 和 GPIOLib。它们是根据引脚使用情况选择的:
今天我就尝试一下GPIOlib,看框图它是用户层的代码可以直接通过char device控制GPIOlib,从而控制GPIO,感觉和单片机的玩法有点像,那么就要跳转去讲GPIOlib的wiki页面,连接如下https://wiki.stmicroelectronics.cn/stm32mpu/wiki/How_to_control_a_GPIO_in_userspace
这个页面中讲了通过命令和程序控制LED灯
我先试试命令
1.检测命令
gpiodetect
2.信息命令
gpioinfo
这里信息还挺多的,我就不截图了,直接上终端的内容
root@stm32mp1:~# gpioinfo
gpiochip0 - 16 lines:
line 0: "PA0" input
line 1: "PA1" input consumer="kernel"
line 2: "PA2" input consumer="kernel"
line 3: "PA3" input consumer="kernel"
line 4: "PA4" input
line 5: "PA5" input
line 6: "PA6" input consumer="kernel"
line 7: "PA7" input
line 8: "PA8" input
line 9: "PA9" input consumer="kernel"
line 10: "PA10" input
line 11: "PA11" input
line 12: "PA12" input consumer="kernel"
line 13: "PA13" input active-low bias=pull-up consumer="User-PA13"
line 14: "PA14" output active-low consumer="blue:heartbeat"
line 15: "PA15" input consumer="kernel"
gpiochip1 - 16 lines:
line 0: "PB0" input
line 1: "PB1" input
line 2: "PB2" input consumer="kernel"
line 3: "PB3" input consumer="kernel"
line 4: "PB4" input consumer="kernel"
line 5: "PB5" input
line 6: "PB6" input consumer="kernel"
line 7: "PB7" input consumer="kernel"
line 8: "PB8" input consumer="kernel"
line 9: "PB9" input consumer="kernel"
line 10: "PB10" input
line 11: "PB11" input consumer="kernel"
line 12: "PB12" input consumer="kernel"
line 13: "PB13" input
line 14: "PB14" input consumer="kernel"
line 15: "PB15" input consumer="kernel"
gpiochip2 - 16 lines:
line 0: "PC0" input
line 1: "PC1" input consumer="kernel"
line 2: "PC2" input
line 3: "PC3" input
line 4: "PC4" input consumer="kernel"
line 5: "PC5" input consumer="kernel"
line 6: "PC6" input consumer="kernel"
line 7: "PC7" input consumer="kernel"
line 8: "PC8" input consumer="kernel"
line 9: "PC9" input consumer="kernel"
line 10: "PC10" input consumer="kernel"
line 11: "PC11" input consumer="kernel"
line 12: "PC12" input consumer="kernel"
line 13: "PC13" input
line 14: "PC14" input
line 15: "PC15" input
gpiochip3 - 16 lines:
line 0: "PD0" input consumer="kernel"
line 1: "PD1" input consumer="kernel"
line 2: "PD2" input consumer="kernel"
line 3: "PD3" input consumer="kernel"
line 4: "PD4" input consumer="kernel"
line 5: "PD5" input consumer="kernel"
line 6: "PD6" input consumer="kernel"
line 7: "PD7" input consumer="kernel"
line 8: "PD8" input consumer="kernel"
line 9: "PD9" input consumer="kernel"
line 10: "PD10" input consumer="kernel"
line 11: "PD11" input consumer="kernel"
line 12: "PD12" input consumer="kernel"
line 13: "PD13" input
line 14: "PD14" input consumer="kernel"
line 15: "PD15" input consumer="kernel"
gpiochip4 - 16 lines:
line 0: "PE0" input consumer="kernel"
line 1: "PE1" input
line 2: "PE2" input consumer="kernel"
line 3: "PE3" input consumer="kernel"
line 4: "PE4" input consumer="kernel"
line 5: "PE5" input
line 6: "PE6" input
line 7: "PE7" input consumer="kernel"
line 8: "PE8" input consumer="kernel"
line 9: "PE9" input consumer="kernel"
line 10: "PE10" input
line 11: "PE11" input consumer="kernel"
line 12: "PE12" output consumer="panel-backlight"
line 13: "PE13" input consumer="kernel"
line 14: "PE14" input consumer="kernel"
line 15: "PE15" input consumer="kernel"
gpiochip5 - 16 lines:
line 0: "PF0" input consumer="interrupt"
line 1: "PF1" input consumer="kernel"
line 2: "PF2" input consumer="kernel"
line 3: "PF3" input consumer="kernel"
line 4: "PF4" input consumer="kernel"
line 5: "PF5" input consumer="interrupt"
line 6: "PF6" input consumer="kernel"
line 7: "PF7" input consumer="kernel"
line 8: "PF8" input
line 9: "PF9" input
line 10: "PF10" input
line 11: "PF11" input
line 12: "PF12" input consumer="kernel"
line 13: "PF13" input
line 14: "PF14" input
line 15: "PF15" input
gpiochip6 - 16 lines:
line 0: "PG0" input consumer="kernel"
line 1: "PG1" input
line 2: "PG2" input consumer="kernel"
line 3: "PG3" input
line 4: "PG4" input consumer="kernel"
line 5: "PG5" input consumer="kernel"
line 6: "PG6" input consumer="kernel"
line 7: "PG7" input consumer="kernel"
line 8: "PG8" input consumer="kernel"
line 9: "PG9" input consumer="kernel"
line 10: "PG10" input consumer="kernel"
line 11: "PG11" input consumer="kernel"
line 12: "PG12" input consumer="interrupt"
line 13: "PG13" input consumer="kernel"
line 14: "PG14" input consumer="kernel"
line 15: "PG15" input
gpiochip7 - 15 lines:
line 0: "PH0" input
line 1: "PH1" input
line 2: "PH2" output active-low consumer="reset"
line 3: "PH3" input
line 4: "PH4" input active-low bias=pull-up consumer="cd"
line 5: "PH5" input
line 6: "PH6" input consumer="kernel"
line 7: "PH7" input
line 8: "PH8" input consumer="kernel"
line 9: "PH9" input consumer="kernel"
line 10: "PH10" input
line 11: "PH11" input
line 12: "PH12" input consumer="kernel"
line 13: "PH13" input consumer="kernel"
line 14: "PH14" input consumer="kernel"
gpiochip8 - 8 lines:
line 0: "PI0" input
line 1: "PI1" input consumer="kernel"
line 2: "PI2" input consumer="kernel"
line 3: "PI3" input consumer="kernel"
line 4: "PI4" input
line 5: "PI5" input
line 6: "PI6" input
line 7: "PI7" output consumer="enable"
gpiochip9 - 16 lines:
line 0: unnamed input
line 1: unnamed input
line 2: unnamed output active-low consumer=reset
line 3: unnamed output
line 4: unnamed output
line 5: unnamed input
line 6: unnamed input
line 7: unnamed input
line 8: unnamed input
line 9: unnamed output active-low consumer=PHY reset
line 10: unnamed output active-low consumer=PHY reset
line 11: unnamed output active-low consumer=reset
line 12: unnamed input
line 13: unnamed output consumer=shutdown
line 14: unnamed input
line 15: unnamed input
3.get命令
我是点灯,属于输出,不要输入,get命令我就不尝试了,有兴趣的去wiki自行阅读
4.set命令
之前开箱篇说了LED3是linux的心跳灯,那我就用LED4,对应的是PA13
gpioset -t 500ms -c gpiochip9 14=active
再来试试用代码,wiki页面中使用的是PA14,这个引脚不能再用了,那我还得改造一下代码,刚才命令试了LED7,现在换成LED6的。具体的编译、下载、运行啥的我这边就不赘述了,可以参照看上一篇helloworld
.c如下
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/gpio.h>
int main(int argc, char **argv)
{
struct gpiohandle_request req;
struct gpiohandle_data data;
char chrdev_name[20];
int fd, ret;
strcpy(chrdev_name, "/dev/gpiochip9");
/* Open device: gpiochip9 for GPIO MCP */
fd = open(chrdev_name, 0);
if (fd == -1) {
ret = -errno;
fprintf(stderr, "Failed to open %s\n", chrdev_name);
return ret;
}
/* request GPIO line: GPIO_9_15 */
req.lineoffsets[0] = 15;
req.flags = GPIOHANDLE_REQUEST_OUTPUT;
memcpy(req.default_values, &data, sizeof(req.default_values));
strcpy(req.consumer_label, "led_gpio_mcp_15");
req.lines = 1;
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
if (ret == -1) {
ret = -errno;
fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n",
ret);
}
if (close(fd) == -1)
perror("Failed to close GPIO character device file");
/* Start led blinking */
while(1) {
data.values[0] = !data.values[0];
ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret == -1) {
ret = -errno;
fprintf(stderr, "Failed to issue %s (%d)\n",
"GPIOHANDLE_SET_LINE_VALUES_IOCTL", ret);
}
sleep(1);
}
/* release line */
ret = close(req.fd);
if (ret == -1) {
perror("Failed to close GPIO LINEHANDLE device file");
ret = -errno;
}
return ret;
}
makeflie如下
PROG = led
SRCS = led.c
OBJS = $(SRCS:.c=.o)
CLEANFILES = $(PROG)
# Add / change option in CFLAGS if needed
# CFLAGS += <new option>
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS)
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
all: $(PROG)
clean:
rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~
看看效果
好了,点灯篇结束
本帖最后由 不爱胡萝卜的仓鼠 于 2023-12-17 15:13 编辑