linux gpio驱动

本文介绍了在Linux系统中使用sysfs接口和内核API操作GPIO的步骤。首先通过/sys/class/gpio导出和设置GPIO,然后展示了如何在用户空间通过echo命令设置方向和输出值。接着,详细解释了内核空间中如gpio_request、gpio_free等接口的用法,并提供了一个简单的LED控制驱动模块的实现,包括打开、关闭、ioctl操作。最后,展示了驱动的注册、设备节点创建及GPIO资源的申请和配置过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、sysfs用户空间

/sys/class/gpio目录下有两个节点export和unexport

1.1 操作的基本步骤

1. 导出
/sys/class/gpio# echo 32 > export
2. 设置方向 out,in
/sys/class/gpio# echo out > gpio32/direction
3. 查看方向
/sys/class/gpio# cat gpio32/direction
4. 设置输出
/sys/class/gpio# echo 1 > gpio32/value
5. 查看输出值
/sys/class/gpio# cat gpio32/value
6. 取消导出
/sys/class/gpio# echo 32> unexport

2、内核空间

2.1 常用接口介绍

1、申请GPIO
int gpio_request(unsigned gpio, const char *label);
2、释放GPIO
void gpio_free(unsigned gpio);
3、设置GPIO为输入
int gpio_direction_input(unsigned gpio);
4、设置GPIO为输出
int gpio_direction_output(unsigned gpio, int value);
5、获取GPIO的电平
int gpio_get_value(unsigned int gpio);
6、设置GPIO的电平
void gpio_set_value(unsigned int gpio, int value)

简单的demo

#include<linux/init.h>
#include <linux/module.h>
#include <linux/leds.h>
#include <linux/io.h>
#include <linux/semaphore.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <plat/mux.h>
#include <linux/gpio.h>
#include <linux/uaccess.h>


#define DEV_NAME "gpio_led"

#define GPIO_TO_PIN(bank, gpio)	(32 * (bank) + (gpio))
static int major = 0;//主设备号
struct gpio_dev{
	dev_t dev_id;//设备号
	struct cdev cdev;
	struct class *cls;
}gpio;

static struct gpio_dev fgpio; 


// 打开和关闭函数
static int light_open(struct inode *inode,struct file *filp)
{
	return 0;
}

static int light_close(struct inode *inode,struct file *filp)
{
	return 0; 
}



static long light_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{

	switch(cmd)
	{
	  case 0:
		gpio_set_value(GPIO_TO_PIN(3,17), 0); 
	  break;
	  case 1:
		gpio_set_value(GPIO_TO_PIN(3,17), 1); 
	  break;
	default:
	    return -ENOTTY;
	}

	return 0;
} 


static struct file_operations light_fops = 
{
	.owner = THIS_MODULE,
	.open = light_open,
	.release = light_close,
	.unlocked_ioctl = light_ioctl,
};

static int __init light_init(void)
{
	dev_t dev_id;
	int ret;
	// 1申请设备号
	if (major)  // 静态申请
	{
		dev_id = MKDEV(major, 0);
		ret = register_chrdev_region(dev_id, 1, DEV_NAME);
	}
	else{  // 动态
		ret = alloc_chrdev_region(&dev_id, 0, 1, DEV_NAME);
		//获取主设备号
		major = MAJOR(dev_id);
		printk("major=%d\n", major);
		}
	fgpio.dev_id = dev_id;//把申请的设备号返回到结构中去	
	//2初始化注册cdev
	cdev_init(&fgpio.cdev,&light_fops);
	cdev_add(&fgpio.cdev,dev_id,1);

	//自动创建设备节点:/dev/gpio_led
	fgpio.cls = class_create(THIS_MODULE,DEV_NAME);
	device_create(fgpio.cls,NULL,dev_id,NULL,DEV_NAME);

    //4.申请GPIO资源,配置GPIO为输出,输出0
    gpio_request(GPIO_TO_PIN(3,17), "LED1");
    gpio_direction_output(GPIO_TO_PIN(3,17), 0);	

	return 0;

}

static void __exit light_exit(void)
{
	dev_t dev = MKDEV(major,0);
	
	//1、删除设备节点
	device_destroy(fgpio.cls,dev);
	class_destroy(fgpio.cls);
	//2卸载cdev
	cdev_del(&fgpio.cdev);

	//3.释放设备号
	unregister_chrdev_region(dev, 1);
	
}

module_init(light_init);
module_exit(light_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("baiseyuzhou");

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值