文章目录
Linux内核GPIO操作库函数
int gpio_request(unsigned gpio, const char *label)
void gpio_free(unsigned gpio)
int gpio_direction_output(unsigned gpio, int value)
int gpio_direction_input(unsigned gpio)
int gpio_set_value(unsigned gpio, int value)
int gpio_get_value(unsigned gpio)
示例:实现注册驱动后指定LED灯亮起
示例具体代码
执行过程
总结
Linux内核GPIO操作库函数
GPIO操作分为“输入操作”和“输出操作”,“输入操作”的GPIO引脚的电平由外设决定,“输出操作”的GPIO引脚的电平由CPU决定,Linux内核已经实现以下关于GPIO调用的库函数,只需要在需要的适合调用即可:
int gpio_request(unsigned gpio, const char *label)
- 函数功能:CPU的任何一个GPIO引脚硬件资源对于Linux内核来说都是一种宝贵的资源,如果某个内核程序要想访问这个GPIO引脚资源,首先必须想Linux内核申请资源(类似malloc)
- 参数说明:
- gpio:GPIO引脚硬件在linux内核中的软件编号,也就是
- 对于任何一个GPIO引脚,linux内核都给分配一个唯一的
- 软件编号(类似GPIO引脚的身份证号)
- GPIO硬件 GPIO软件编号
- GPIOC12 PAD_GPIO_C+12
- GPIOB11 PAD_GPIO_B+11
- … …
- label:给申请的硬件GPIO引脚指定的名称,随便取。
- 返回值:看内核大神的代码如何判断即可,照猫画虎
- 头文件:
- #include
- #include
- #include
- #include
void gpio_free(unsigned gpio)
- 函数功能:内核程序如果不再使用访问GPIO硬件资源记得要将硬件资源归还给linux内核,类似free。
- 参数:
- gpio:要释放的GPIO硬件资源对应的软件编号
int gpio_direction_output(unsigned gpio, int value)
- 函数功能:配置GPIO引脚为输出功能,并且输出一个value值(1高电平/0低电平)
- 参数:
- gpio:GPIO硬件对应的软件编号
- value:输出的值
int gpio_direction_input(unsigned gpio)
- 函数功能:配置GPIO为输入功能
int gpio_set_value(unsigned gpio, int value)
- 函数功能:设置GPIO引脚的输出值为value(1:高/0:低),前提是必须首先将GPIO配置为输出功能
int gpio_get_value(unsigned gpio)
- 函数功能:获取GPIO引脚的电平状态,返回值就是引脚的电平状态(返回1:高电平;返回0:低电平),此引脚到底是输入还是输出没关系!
示例:实现注册驱动后指定LED灯亮起
- 板子上LED灯为共阳极方式连接,所以当CPU输出低电平时LED灯会亮起,高电平时会熄灭。
- 使用板子为三星的S5P6818开发板,上面的LED灯连接的GPIO管脚分别为:GPIO_C_12、GPIO_C_7、GPIO_C_11、GPIO_B_26。
示例具体代码
led_drv.c #include <linux/init.h> #include <linux/module.h> #include <linux/gpio.h> #include <mach/platform.h> //PAD_GPIO_C //声明描述LED硬件相关的数据结构 struct led_resource { int gpio; //GPIO软件编号 char *name; //LED的名称 }; //定义初始化四个LED灯的硬件信息对象 static struct led_resource led_info[] = { { .name = "LED1", .gpio = PAD_GPIO_C+12 }, { .name = "LED2", .gpio = PAD_GPIO_C+7 }, { .name = "LED3", .gpio = PAD_GPIO_C+11 }, { .name = "LED4", .gpio = PAD_GPIO_B+26 } }; //入口:insmod static int led_init(void) { int i; //1.先向内核申请GPIO硬件资源 //2.然后配置GPIO为输出功能,输出0,开灯 for(i = 0; i < ARRAY_SIZE(led_info); i++) { gpio_request(led_info[i].gpio, led_info[i].name); gpio_direction_output(led_info[i].gpio, 0); } printk("led init...\n"); return 0; } //出口:rmmod static void led_exit(void) { int i; //1.输出1,关灯 //2.释放GPIO硬件资源 for(i = 0; i < ARRAY_SIZE(led_info); i++) { gpio_set_value(led_info[i].gpio, 1); gpio_free(led_info[i].gpio); } printk("led exit...\n"); } module_init(led_init); module_exit(led_exit); MODULE_LICENSE("GPL");
- 通过代码能看出当执行insmod led_drv.ko即想Linux内核加载led_drv驱动模块时,根据Linux驱动调用方式会首先执行led_init函数,即实现了指定gpio管脚输出0(点亮LED灯)。
- Makefile:
kernel_dir=/home/ww/ARM/kernel obj-m += led_drv.o all: make -C ${kernel_dir} SUBDIRS=$(PWD) modules clean: make -C ${kernel_dir} SUBDIRS=$(PWD) clean
执行过程
- make进行驱动模块编译
- 在开发板上加载led_drv.ko
- 卸载led_drv驱动
总结
Linux驱动控制GPIO管脚最底层的操作就是通过这几个函数来实现,但是具体到我们真正用到的时候肯定不能仅仅通过一个点亮LED灯来实现,并且现在的LED灯的点亮方式还是通过加载驱动模块的操作来完成的。不过后面我们会需要用户在应用层调用Linux驱动来达到操作底层硬件的基本方法。