linux-GPIO读取以及中断注册

硬件对应

HOME→UART_RING→GPX1_1

BACK→SIM_DET→GPX1_2

SWITCH3→AP_SLEEP→GPC0_3

SWITCH4→XEINT6→GPX0_6

GPIO读取

步骤:

  1. 申请GPIO  gpio_request(EXYNOS4_GPX1(1),"HOME");
  2. 设置模式,输入模式  s3c_gpio_cfgpin(EXYNOS4_GPX1(1),S3C_GPIO_INPUT);
  3. 设置上下拉,既不上拉也不下拉  s3c_gpio_setpull(EXYNOS4_GPX1(1),S3C_GPIO_PULL_NONE);
  4. 读取  gpio_get_value(EXYNOS4_GPC0(3));

 

中断注册

头文件

#include <linux/irq.h>
#include <linux/interrupt.h>

结合技术手册查找中断号:

HOME→UART_RING→GPX1_1  → GPX1CON→KP_COL[1] →XEINT_9

中断注册函数:

static inline int __must_check
request_irq(
                unsigned int irq, 
                irq_handler_t handler, 
                unsigned long flags,
                const char *name, 
                void *dev_id)

参数:

  1. irq中断号。(和平台架构相关,结合datasheet以及平台文件) IRQ_EINT(x)
  2. 中断处理函数 中断发生时,系统调用这个函数,dev_id参数将被传递给它
  3. 中断标记  IRQ_TYPE_EDGE_FALLING  上升或下降中断触发
  4. 中断名字
  5. dev_id 一般使用设备的设备结构体或者NULL 

返回值:request_irq()返回0表示成功,返回-EINVAL表示中断号无效或处理函数指针为NULL,返回-EBUSY表示中断已经被占用,且不能被共享。

中断卸载函数:

void free_irq(unsigned int irq, void *dev_id)

中断服务函数:

irq_handler_t irq16_handler(int irq,void *dev_id)

简单程序

驱动程序:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/device.h>

#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-exynos4.h>

#include <linux/irq.h>
#include <linux/interrupt.h>

#include <asm/uaccess.h>


MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("SZA");

static dev_t dev;
static int major_num;
static int minor_num;
#define CHR_NAME "Epic_chr"
#define CLS_NAME "Epic_cls"
#define DEV_NAME "Epic_dev"

static int gpios[] = {EXYNOS4_GPX1(1),EXYNOS4_GPX1(2),EXYNOS4_GPC0(3),EXYNOS4_GPX0(6),EXYNOS4_GPL2(0)};

static irq_handler_t home_handler(int irq,void *dev_id)
{
	printk("home--\n");
	gpio_set_value(gpios[4],1);
	return IRQ_HANDLED;
}

static irq_handler_t back_handler(int irq,void *dev_id)
{
	printk("back--\n");
	gpio_set_value(gpios[4],0);
	return IRQ_HANDLED;
}


static int pocky330_open(struct inode *inode, struct file *file)
{
	int i;
	printk("pocky330_open \n");
	for(i=0;i<4;i++)
	{
		gpio_request(gpios[i],"gpio");
		s3c_gpio_cfgpin(gpios[i],S3C_GPIO_INPUT);
		s3c_gpio_setpull(gpios[i],S3C_GPIO_PULL_NONE);
	}
	
	return 0;
}

static int pocky330_release(struct inode *inode, struct file *file)
{
	int i;
	printk("pocky330_release \n");
	for(i=0;i<4;i++)
	{
		gpio_free(gpios[i]);
	}
	return 0;
}

static long pocky330_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{	
	if(cmd == 3)
	{
		return gpio_get_value(gpios[2]);
	}
	else if(cmd == 4)
	{
		return gpio_get_value(gpios[3]);
	}
	else
	{
		printk(KERN_EMERG "cmd err!! \n");
	}
	return 0;
}


static struct cdev my_cdev;
static struct file_operations my_fops = {
	.owner = THIS_MODULE,
	.open = pocky330_open,
	.release = pocky330_release,
	.unlocked_ioctl = pocky330_unlocked_ioctl,
};

static struct class *myclass;

static int pocky330_init(viod)
{
	int ret;
	printk("pocky330_init!!! \n");
	ret = alloc_chrdev_region(&dev,minor_num,1,CHR_NAME);
	if(ret < 0)
	{
		printk("alloc_chrdev_region fail!!! \n");
	}
	cdev_init(&my_cdev,&my_fops);
	cdev_add(&my_cdev, dev, 1);
	myclass = class_create(THIS_MODULE,CLS_NAME);
	device_create(myclass,NULL,dev,NULL,DEV_NAME);
	gpio_request(gpios[4],"led");
	s3c_gpio_cfgpin(gpios[4],S3C_GPIO_OUTPUT);
	gpio_set_value(gpios[4],0);
	request_irq(IRQ_EINT(9),home_handler,IRQ_TYPE_EDGE_FALLING,"home",NULL);
	request_irq(IRQ_EINT(10),back_handler,IRQ_TYPE_EDGE_FALLING,"back",NULL);
	return 0;
}

static void pocky330_exit(void)
{
	gpio_free(gpios[4]);
	
	cdev_del(&my_cdev);
	device_destroy(myclass,dev);
	class_destroy(myclass);
	unregister_chrdev_region(dev,1);
    free_irq(IRQ_EINT(9),NULL);
    free_irq(IRQ_EINT(10),NULL);
}
module_init(pocky330_init);
module_exit(pocky330_exit);

应用程序:

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main(void){
	int fd,io_val;;
	char *path = "/dev/Epic_dev";
	fd = open(path,O_RDWR|O_NDELAY);
	if(fd < 0)
	{
		printf("open led failed!!");
	}
	else
	{
		io_val = ioctl(fd,3,0);
		printf("switch3 is %d",io_val);
		io_val = ioctl(fd,4,0);
		printf("switch4 is %d",io_val);
	}
	
	close(fd);
	return 0;
	
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值