Linux控制GPIO技巧详解 (linux下控制gpio)

在嵌入式系统开发中,GPIO(General-purpose input/output)端口是一个重要的概念。它允许将一个数字输入或输出信号连接到嵌入式系统外部的设备,如LED灯、开关、传感器、马达等各种设备上。因此,掌握GPIO编程技巧是至关重要的,它可以帮助嵌入式开发者在各种不同的应用场景中,轻松地实现不同的IO端口控制。

而在Linux系统中,GPIO端口的管理和控制存在许多不同的方法,这篇文章将深入探讨其中的细节,帮助读者更好地掌握Linux控制GPIO技巧。

GPIO系统文件

在Linux系统中,GPIO控制是通过引脚的读写操作来实现的。这些引脚通常被称为“GPIO口”。而要对GPIO口进行读写操作,我们需要使用Linux系统的GPIO系统文件。在Linux内核中,这些文件通常存储在/sys/class/gpio目录下。

例如,如果我们需要扫描GPIO 1口的状态,我们可以使用以下命令:

echo 1 > /sys/class/gpio/export

echo in > /sys/class/gpio/gpio1/direction

cat /sys/class/gpio/gpio1/value

上述命令的意思是,首先将GPIO 1口引脚信息写入exports文件,之后设置GPIO 1口为输入模式,最后读取GPIO 1口的状态。如果口的状态是高电平,这个命令将返回1;如果状态是低电平,则返回0。

内核模块

另一种控制GPIO端口的方法是使用Linux内核模块。内核模块是一段代码,可以嵌入到Linux内核中,以扩展或更改Linux系统内核的功能。使用内核模块,我们可以编写C代码来访问GPIO口,将其设置为输入或输出模式,并读取或写入其状态。

以下是一个简单的内核模块示例,它可以检测GPIO端口状态的变化并在日志中记录这些变化:

“`

#include

#include

#include

#include

static unsigned int gpioLED = 4; // 用于操作的GPIO口

static int __init gpio_init(void) {

int result = 0;

printk(KERN_INFO “GPIO test: Initializing the GPIO LED\n”); // 写入内核日志

if (!gpio_is_valid(gpioLED)) {

printk(KERN_INFO “GPIO test: invalid LED GPIO\n”); // 写入内核日志

return -ENODEV;

}

gpio_request(gpioLED, “sysfs”);

gpio_direction_output(gpioLED, 1); // 设置GPIO口为输出模式,初始高电平状态

printk(KERN_INFO “GPIO test: GPIO LED is initialized\n”); // 写入内核日志

return result;

}

static int __exit gpio_exit(void) {

gpio_set_value(gpioLED, 0); // 关闭GPIO口

gpio_free(gpioLED);

printk(KERN_INFO “Goodbye!\n”); // 写入内核日志

}

module_init(gpio_init);

module_exit(gpio_exit);

“`

这个示例将GPIO 4口设置为输出模式,并将其初始状态设置为高电平。在这个简单的内核模块示例中,我们使用了内核核心GPIO API以及其他的内核API。但是,在实际开发中,由于内核的巨大复杂性,我们通常需要使用GPIO库来简化GPIO调用,例如libgpiod、gpio_sysfs、bcm2835等第三方贡献库。

库函数

GPIO库是一种快速、简便的方式来控制GPIO端口。这些库通过封装底层GPIO调用,提供了一组更具可用性的API,使用更为高效和便捷。下面是一个使用libgpiod库控制GPIO的例子:

“`

#include

#include

int mn(void)

{

int ret = -1; // 初始化返回值

gpiochip_gpiospec_t spec; // 创建一个gpiochip_gpiospec_t结构体

spec.line_offset = 0; // GPIO口的偏移地址

spec.flags = GPIOD_LINE_REQUEST_INPUT; // 请求GPIO口的输入模式

gpio_line_request(“gpiochip0”, &spec, false); // 请求GPIO口并检查返回值

while (ret

ret = gpio_line_get_value_fd(spec.fd); // 读取GPIO口的状态

printf(“%d\n”, ret);

}

gpio_line_release(spec.fd); // 释放GPIO口

return 0;

}

“`

在这个例子中,我们使用了Linux底层GPIO调用库libgpiod。它提供了一组使用方便的API函数,可以轻松控制GPIO端口。在这个例子中,我们可以读取来自连接设备的GPIO口,在屏幕上输出状态。

相关问题拓展阅读:

14-Linux gpio模拟spi

首先是spidev,要在/dev/下面产生设备文件,需要spidev的支持

使用的是gpio模拟spi,gpio模拟spi的时序原理是bitbang文件实现的,所以这个也需要打开,如果是在openwrt下动态加载的话就是如下两个配置

如果是直接内核的话是如下两个

跟I2C的arch层一样,主要是devices的添加和board_info的添加,如下

对于platform_add_devices,因为是使用spi_gpio,所以name是”spi_gpio”这样才可以与driver里面的spi_gpio相互匹配probe到。

因为SPI是可以一个总线上面挂多个,然后通过片选脚CS进行硬件切换,所以这变有个num_chipselect需要设置,如果有2个设置就设置2,一个设备就设置1,这边设置好之后,后面board_info也要有对应的个数,而且片选引脚需要不同。

I2C是通过每个设备有自己不同的地址,通过地址来进行软件切换。

对于board_info使用的是spidev,drivers/spi/spidev.c文件,该文件的内容是注册一个spidev驱动。该驱动是一个字符设备驱动。

如果设备与驱动匹配,那么就会执行spidev_probe()的内容。在spidev_probe()函数中会调用device_create()成功后在 /dev 目录下就会生成 spidev 相关的设备节点。

这边有几个参数要注意:

调试过程想看一些细节的debug信息可以打开内核的动态debug信息,这个在以前的print system里面有

printk的等级设置成8.

开始

定位到是 spi_gpio_request 的时候报错

后仿橘者面就将zkernel/3.10.49/arch/mips/mtk/ziroom/zrmt7628.c里面GPIO的信息调整下,

因为SPI的引脚和LED的引脚号一样

,内核不知道哪里会检测到。

修改后打印备薯如下:

之后在/dev/下面就生成了spidev1.0的设备

有了/dev/spidev1.0设备之后,就可以在应用成操作改设备收发数据。

在drivers/spi/spidev.c里面已经封装好了ioctl的对应接口,根据这些伍禅接口就可以测试使用。

在Documentation/spi/spidev_test.c下面有个应用层的实例,打开看下就清除了。

$(cc) spidev_test.c -o spidev_test生成可执行文件spidev_test

然后拷贝到板子上,将MOSI和MISO短接就可以测试回环数据是否正常。

有逻辑分析仪的接上logic看波形就更加直观。

gpio模拟SPI:

在ARM Linux下使用GPIO模拟SPI时序详解:

linux SPI驱动:

关于linux下控制gpio的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » Linux控制GPIO技巧详解 (linux下控制gpio)