mini2440 KEY按键设备驱动(中断模式和查询模式)源代码--(宋宝华框架)

本文介绍了一种mini2440平台上的按键设备驱动程序实现,包括中断模式和查询模式两种方式。通过详细展示代码,解释了如何配置寄存器、处理按键中断以及查询按键状态。

/*****************************************************************

mini2440 KEY按键设备驱动(中断模式和查询模式)源代码

*****************************************************************/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>

//使用宋宝华推荐的普通字符设备框架
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#include <linux/pagemap.h>
#include <linux/device.h>
#include <asm/io.h> 
//#include <asm/arch/regs-gpio.h>  //2.6.12
#include <mach/regs-gpio.h>    // 2.6.32
#include <linux/sched.h>  
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/workqueue.h>
#include <linux/semaphore.h>

#include <linux/wait.h>
#include <linux/timer.h>
#include <linux/version.h>
#include <mach/irqs.h>

#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <mach/regs-irq.h>
#include <mach/irqs.h>
#include <mach/io.h>

#include <asm/dma.h>

#define  LEDOFF 0
#define  LEDON 1
//#define DEMO_MAJOR 235  //静态分配
#define DEMO_MAJOR 0 //动态分配
#define DEMO_MINOR 0
int devmajor = DEMO_MAJOR;
int devminor =  DEMO_MINOR;
dev_t dev = 0;

//#define KEYIRQ  //中断模式
#define KEYPOLL  //查询模式

//***************************************************//
//***************key查询模式*********************//
//***************************************************//
#ifdef KEYPOLL   //查询模式
//key
static void __iomem *key_base;
#define rGPGCON     (*(volatile unsigned long *)(key_base + 0x00))
#define rGPGDAT     (*(volatile unsigned long *)(key_base + 0x04)) 
#define rGPGUP     (*(volatile unsigned long *)(key_base + 0x08))
//new
volatile unsigned *rGPBCON_p;
volatile unsigned *rGPBDAT_p;

//设备结构
//设备结构
struct DEMO_dev
{
 struct cdev cdev;   /* Char device structure*/
};

struct DEMO_dev *DEMO_devices;
struct class *key_class;


int DEMO_open(struct inode *inode, struct file *filp)
{
 struct DEMO_dev *demo_dev;
 unsigned int temp;

 filp->private_data=DEMO_devices;

 

 
 /*配置GPGCON input: [00]*/
 temp = rGPGCON;
 temp &= ~((3<<22)|(3<<14)|(3<<12)|(3<<10)|(3<<6)|(3<<0));
 rGPGCON = temp;

 /*配置CPGUP, 每位置1*/
 temp = rGPGUP;
 temp |= ((1<<11)|(1<<7)|(1<<6)|(1<<5)|(1<<3)|(1<<0));
 rGPGUP = temp;
 
 return 0;
}
int DEMO_release(struct inode *inode, struct file *filp)
{
 
 return 0;
}
int DEMO_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
{
 return 0; 
}

//也可以使用DEMO_write来替代DEMO_ioctl
ssize_t DEMO_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
  return 0;      
}

ssize_t DEMO_read(struct file *filp,char __user *buff,size_t size,loff_t *offp)
{
 int count;
 count = sizeof(int);
 int temp,key1,key2; 

 temp =rGPGDAT;
 
 if (copy_to_user(buff, &temp, count))
       {
   return -EFAULT;
       }
     return 0;

}

struct file_operations DEMO_fops = {
 .owner = THIS_MODULE,
 .ioctl = DEMO_ioctl,
 .open = DEMO_open,
 .write = DEMO_write,
 .read =  DEMO_read,
 .release=DEMO_release,
};

/*******************************************************
                MODULE ROUTINE
*******************************************************/

void DEMO_cleanup_module(void)
{
 
 iounmap(key_base);

 if (DEMO_devices)
 {
  cdev_del(&DEMO_devices->cdev);//5 从系统中移除一个字符设备
  kfree(DEMO_devices);
 }
      device_destroy(key_class, MKDEV(devmajor, 0));         //delete device node under /dev
      class_destroy(key_class);                               //delete class created by us
 unregister_chrdev_region(dev,1);// 6 释放设备编号
}

int DEMO_init_module(void)
{
 int result;

 if(devmajor)
 {
  dev = MKDEV(devmajor, devminor); // 1 获得设备号
  result = register_chrdev_region(dev, 1, "key_driver"); // 2 分配设备编号
 }
 else
 {
  result = alloc_chrdev_region(&dev, devminor, 1, "key_driver");
 // //2  动态分配设备编号
  devmajor = MAJOR(dev);
 }
 if (result < 0)
 {
  printk(KERN_WARNING "scull: can't get major %d\n", devmajor);
  return result;
 }
 
 printk(KERN_WARNING "led get major: %d\n", devmajor);
 DEMO_devices = kmalloc(sizeof(struct DEMO_dev), GFP_KERNEL);//分配内存给本设备结构体

 if (!DEMO_devices)
 {
  result = -ENOMEM;
  goto fail;
 }
 
 memset(DEMO_devices, 0, sizeof(struct DEMO_dev));

 cdev_init(&DEMO_devices->cdev, &DEMO_fops);//(1)  // 字符设备的注册,即将结构嵌入到自己的设备中
 DEMO_devices->cdev.owner = THIS_MODULE;
 DEMO_devices->cdev.ops = &DEMO_fops; //(2)
 result = cdev_add (&DEMO_devices->cdev, dev, 1);// 4 把本设备放内核中
 if(result)
 {
  printk(KERN_NOTICE "Error %d adding DEMO\n", result);
  goto fail;
 }
  //创建节点方法2  使用函数自动创建  方法1是手动创建#mknod /dev/test c 235 0
// 下面方法2.6.32支持。2.6.18 2.6.12不支持

//ioremap
   //rGPBCON_p=(volatile unsigned  *)ioremap((volatile unsigned *)0x56000010,4);
 //rGPBDAT_p=(volatile unsigned  *)ioremap((volatile unsigned *)0x56000014,4);

 key_base=(volatile unsigned*)ioremap((volatile unsigned *)0x56000060,12);
 
    /* create your own class under /sysfs   2.6.32*/
   key_class = class_create(THIS_MODULE, "key_class");
   if(IS_ERR(key_class))
   {
     printk("Err: failed in creating class.\n");
     return -1;
    }
 
   /* register your own device in sysfs, and this will cause udev to create corresponding device node */
    device_create( key_class, NULL, MKDEV(devmajor, 0),  NULL, "key_driver");
 
 return 0;

fail:
 DEMO_cleanup_module();
 return result;
}

module_init(DEMO_init_module);
module_exit(DEMO_cleanup_module);
MODULE_AUTHOR("su");
MODULE_LICENSE("GPL");

 

 


//***************************************************//
//***************key中断模式*********************//
//***************************************************//

#elif defined KEYIRQ   //KEY中断模式

//设备结构
struct KEY_dev
{
 struct cdev cdev;   /* Char device structure*/
 struct semaphore sem;
 wait_queue_head_t rq; /* 定义等待队列头*/
 int key;
 //底半部的工作队列方法
 struct work_struct my_wq; //定义一个工作队列
 
};
struct KEY_dev *key_devices; //key_devices
static int key_flag=0;

#define key_dev_num 1
//static unsigned long polling_jffs=0;
struct class *key_class; //

/*定义6个按键对应的中断号,在mach头文件中去找*/
//irqs.h中
static int KeyIrqArray[6]=
{
  IRQ_EINT8,
  IRQ_EINT11,
  IRQ_EINT13,
  IRQ_EINT14,
  IRQ_EINT15,
  IRQ_EINT19
};

static irqreturn_t key1_interrupt(int irq, void *dev_id)
{
 //*  有了操作系统后这一部分可以省略
 volatile unsigned temp=0;
 temp = __raw_readl(S3C2410_EINTPEND);
 temp |=(1<<8);
 __raw_writel(temp,S3C2410_EINTPEND);

 temp = __raw_readl(S3C2410_SRCPND);
 temp |=(1<<5);
 __raw_writel(temp,S3C2410_SRCPND);

 temp = __raw_readl(S3C2410_INTPND);
 temp |=(1<<5);
 __raw_writel(temp,S3C2410_INTPND);
 //*/
 
 //中断处理方式一:在中断函数中直接处理
 //获取键盘值
 key_devices->key=1;  //key记录第几个按键按下
 key_flag=1;
 wake_up_interruptible(&(key_devices->rq));/*唤醒等待队列*/
 printk("****key1\n");
 return IRQ_HANDLED; 
}

// 按键key2采用底半部tasklet的方法
void key2_do_tasklet(unsigned long code)
{
 //中断处理方式一:在中断函数中直接处理
 //获取键盘值
 key_devices->key=2; //key记录第几个按键按下
 key_flag=1;
 wake_up_interruptible(&(key_devices->rq));/*唤醒等待队列*/
 printk("tasklet ***------ key2\n");
}
DECLARE_TASKLET(key_tasklet,key2_do_tasklet,0); //
static irqreturn_t key2_interrupt(int irq,void *dev_id)
{
 tasklet_schedule(&key_tasklet);
 return IRQ_HANDLED;
}

// 按键key3采用底半部工作队列的方法
void key3_work_func(unsigned long code)
{
 //获取键盘值
 key_devices->key=3;
 key_flag=1;
 wake_up_interruptible(&(key_devices->rq));/*唤醒等待队列*/
 printk("****key3\n");
}
static irqreturn_t key3_interrupt(int irq, void *dev_id)
{
 
 schedule_work(&key_devices->my_wq);
 
 return IRQ_HANDLED;
}

static irqreturn_t key4_interrupt(int irq, void *dev_id)
{
 
 //中断处理方式一:在中断函数中直接处理
 //获取键盘值
 key_devices->key=4;  //key记录第几个按键按下
 key_flag=1;
 wake_up_interruptible(&(key_devices->rq));/*唤醒等待队列*/
 printk("****key4\n");
 return IRQ_HANDLED;
}
static irqreturn_t key5_interrupt(int irq, void *dev_id)
{
 
 //中断处理方式一:在中断函数中直接处理
 //获取键盘值
 key_devices->key=5;  //key记录第几个按键按下
 key_flag=1;
 wake_up_interruptible(&(key_devices->rq));/*唤醒等待队列*/
 printk("****key5\n");
 return IRQ_HANDLED;
}
static irqreturn_t key6_interrupt(int irq, void *dev_id)
{
 
 //中断处理方式一:在中断函数中直接处理
 //获取键盘值
 key_devices->key=6;  //key记录第几个按键按下
 key_flag=1;
 wake_up_interruptible(&(key_devices->rq));/*唤醒等待队列*/
 printk("****key6\n");
 return IRQ_HANDLED;
}
int key_regist_init(void)
{
 //有了操作系统后,下面这些初始化可以不用写,系统帮你做了
 //*
 volatile unsigned temp = 0;
 
 temp = __raw_readl(S3C2410_GPGCON);
 temp &=~( (3<<22)|(3<<14)|(3<<12)|(3<<10)|(3<<6)|3 );
 temp |=( (2<<22)|(2<<14)|(2<<12)|(2<<10)|(2<<6)|2 );
 __raw_writel(temp,S3C2410_GPGCON);
 
 temp = __raw_readl(S3C2410_GPGUP);
 temp &=~( (1<<11)|(1<<17)|(1<<6)|(1<<5)|(1<<3)|(1<<0) );
 temp |=( (1<<0)|(1<<2) );
 __raw_writel(temp,S3C2410_GPGUP);

 //SRCPND
 //0= The interrupt has not been requested.
 // 1= the interrupt source has asserted the interrupt request.
 // EINT8_23   [5] 0=NOt requested, 1= retuested;
 temp = __raw_readl(S3C2410_SRCPND);
 temp |=(0x1<<5);
 __raw_writel(temp,S3C2410_SRCPND);

 //INTMOD   0= IRQ MODE, 1= FIQ

 // EINT8_23   [5] 0=IRQ, 1= FIQ;
 temp = __raw_readl(S3C2410_INTMOD);
 temp &=~(0x1<<5);
 __raw_writel(temp,S3C2410_INTMOD);
 

 //INTMSK
 //Determine which interrupt source is masked. the maskedinterrupt source will not be service
 // 0= interrupt service is available , 1= interrupt service is masked.
 // EINT8_23   [5] 0=service available, 1= masked;
 //both of set to '0'
 temp =  __raw_readl(S3C2410_INTMSK);
 temp &=~(0x1<<5);
 __raw_writel(temp,S3C2410_INTMSK);

 //INTPND
 //indicate the interrupt request status.
 // 0 = the interrupt has not been requestd, 1= the interrupt source has  asserted the interrupt
 //EINT8_23   [5] 0= not request, 1 = requestd;
 //both of sign bit set to "1"
 temp =  __raw_readl(S3C2410_INTPND);
 temp |=(1<<5);
 __raw_writel(temp,S3C2410_INTPND);


 temp =  __raw_readl(S3C2410_EXTINT1);
 temp &=~((7<<28)|(7<<24)|(7<<20)|(7<<12)|7);
 temp |=((2<<28)|(2<<24)|(2<<20)|(2<<12)|2);
 __raw_writel(temp,S3C2410_EXTINT1);
 
 temp =  __raw_readl(S3C2410_EXTINT2);
 temp &=~(0x7<<12);
 temp |=(0x2<<12);
 __raw_writel(temp,S3C2410_EXTINT2);


 temp =  __raw_readl(S3C2410_EINTMASK);
 temp &=~((1<<19)|(1<<15)|(1<<14)|(1<<13)|(1<<11)|(1<<8));
 __raw_writel(temp,S3C2410_EINTMASK);

 temp =  __raw_readl(S3C2410_EINTPEND);
 temp |=((1<<19)|(1<<15)|(1<<14)|(1<<13)|(1<<11)|(1<<8));
 __raw_writel(temp,S3C2410_EINTPEND);
 //*/
 return 0;
}


int KEY_open(struct inode *inode, struct file *filp)
{
 struct KEY_dev *dev;
 key_regist_init();/*初始化按键寄存器*/
 printk("open ok!");
 dev=container_of(inode->i_cdev,struct KEY_dev,cdev);
 filp->private_data=dev;
 return 0;

}
int KEY_release(struct inode *inode, struct file *filp)
{
 return 0;
}
int KEY_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
{
 return 0;
}


//也可以使用KEY_write来替代KEY_ioctl
ssize_t KEY_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
 return 0;     
}

ssize_t KEY_read(struct file *filp,char __user *buff,size_t count,loff_t *offp)
{
 int ret=0;
 struct KEY_dev *dev=filp->private_data;

 memset(buff,0,count);

 if(key_flag == 1)   //有按键按下的情况
 {
  key_flag=0;
  ret=1;
  if (copy_to_user(buff, &dev->key, 4))
        {
   ret= -EFAULT;
        } 
 }
 else   //没有按键按下的情况
 {
  if(filp->f_flags &O_NONBLOCK) //非阻塞
  {
   return -EAGAIN;
  }
  else //阻塞
  { //调用wait_event_interruptible休眠
   if(wait_event_interruptible(dev->rq,key_flag!=0))//等待时间中断
   {
    return -ERESTARTSYS;
   }
   key_flag = 0;
   ret=1;
   if(copy_to_user(buff,&dev->key,4))
   {
    ret=-EFAULT;
   }
  }
 }
     return ret;
}

 


struct file_operations KEY_fops = {
 .owner = THIS_MODULE,
 .ioctl = KEY_ioctl,
 .open = KEY_open,
 
 .read =  KEY_read,
 .release=KEY_release,
};

/*******************************************************
                MODULE ROUTINE
*******************************************************/

void KEY_cleanup_module(void)
{
 
 dev_t dev;
 dev = MKDEV(devmajor,devminor);
 free_irq(KeyIrqArray[0],NULL);//清除按键中断
 free_irq(KeyIrqArray[1],NULL);
 free_irq(KeyIrqArray[2],NULL);
 free_irq(KeyIrqArray[3],NULL);
 free_irq(KeyIrqArray[4],NULL);
 free_irq(KeyIrqArray[5],NULL);

 if (key_devices)
 {
  cdev_del(&key_devices->cdev);//5 从系统中移除一个字符设备
  kfree(key_devices);
 }
      device_destroy(key_class, MKDEV(devmajor, 0));         //delete device node under /dev
      class_destroy(key_class);                               //delete class created by us
 unregister_chrdev_region(dev,1);// 6 释放设备编号
}

int KEY_init_module(void)
{
 int result;
 dev_t dev = 0;
 if(devmajor)
 {
  dev = MKDEV(devmajor, devminor); // 1 获得设备号
  result = register_chrdev_region(dev, 1, "key_driver"); // 2 分配设备编号
 }
 else
 {
  result = alloc_chrdev_region(&dev, devminor, 1, "key_driver");
 // //2  动态分配设备编号
  devmajor = MAJOR(dev);
 }
 if (result < 0)
 {
  printk(KERN_WARNING "scull: can't get major %d\n", devmajor);
  return result;
 }
 
 printk(KERN_WARNING "led get major: %d\n", devmajor);
 key_devices = kmalloc(sizeof(struct KEY_dev), GFP_KERNEL);//分配内存给本设备结构体

 if (!key_devices)
 {
  result = -ENOMEM;
  goto fail;
 }
 
 memset(key_devices, 0, sizeof(struct KEY_dev));
 init_MUTEX(&key_devices->sem);
 cdev_init(&key_devices->cdev, &KEY_fops);//(1)  // 字符设备的注册,即将结构嵌入到自己的设备中
 key_devices->cdev.owner = THIS_MODULE;
 key_devices->cdev.ops = &KEY_fops; //(2)
 result = cdev_add (&key_devices->cdev, dev, 1);// 4 把本设备放内核中
 if(result)
 {
  printk(KERN_NOTICE "Error %d adding KEY\n", result);
  goto fail;
 }
   //创建节点方法2  使用函数自动创建  方法1是手动创建#mknod /dev/test c 235 0
// 下面方法2.6.32支持。2.6.18 2.6.12不支持

    /* create your own class under /sysfs   2.6.32*/
//自动创建节点(2.6.32以上内核才支持)手动创建方法:mknod /dev/key_driver c 235 0
   key_class = class_create(THIS_MODULE, "key_class");
   if(IS_ERR(key_class))
   {
     printk("Err: failed in creating class.\n");
     return -1;
   }
 
   /* register your own device in sysfs, and this will cause udev to create corresponding device node */
   device_create( key_class, NULL, MKDEV(devmajor, 0),  NULL, "key_driver");
 
 /*1申请按键中断*/
    printk(KERN_NOTICE "&key1_interrupt=%x key1_interrupt=%x\n",&key1_interrupt,key1_interrupt);
 if(request_irq(KeyIrqArray[0],key1_interrupt,IRQ_TYPE_EDGE_FALLING,"simplekey",NULL))
 {        //可设置为IRQ_TYPE_EDGE_RISING上长沿触发,IRQ_TYPE_EDGE_FALLING下降沿触发
          //"simplekey"用于在/proc/interrupts中显示中断的拥有者
  printk("request button irq failed!\n ");
  return -1;
 }
 if(request_irq(KeyIrqArray[1],key2_interrupt,IRQ_TYPE_EDGE_FALLING,"simplekey",NULL))
 {
  printk("request button irq failed!\n ");
  return -1;
 }
 if(request_irq(KeyIrqArray[2],key3_interrupt,IRQ_TYPE_EDGE_FALLING,"simplekey",NULL))
 {
  printk("request button irq failed!\n ");
  return -1;
 }
 if(request_irq(KeyIrqArray[3],key4_interrupt,IRQ_TYPE_EDGE_FALLING,"simplekey",NULL))
 {
  printk("request button irq failed!\n ");
  return -1;
 }
 if(request_irq(KeyIrqArray[4],key5_interrupt,IRQ_TYPE_EDGE_FALLING,"simplekey",NULL))
 {
  printk("request button irq failed!\n ");
  return -1;
 }
 if(request_irq(KeyIrqArray[5],key6_interrupt,IRQ_TYPE_EDGE_FALLING,"simplekey",NULL))
 {
  printk("request button irq failed!\n ");
  return -1;
 }
 init_waitqueue_head(&key_devices->rq);/*初始化等待消息队列*/

 //初始化底半部工作队列方法
 INIT_WORK(&key_devices->my_wq,(void (*) (void *) ) key3_work_func); //最后一个参数NULL不要写否则编译报错(PPT可能有误)
 
 return 0;

fail:
 KEY_cleanup_module();
 return result;
}

module_init(KEY_init_module);
module_exit(KEY_cleanup_module);
MODULE_AUTHOR("hui");
MODULE_LICENSE("GPL");

#endif

 

/*****************************************************************

应用程序key_irq中断模式测试源代码:

*****************************************************************/

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DEV_NAME "/dev/key_driver"
int main(void)
{
 int fd;
 int i;
 int key;
 int retval;
 
 fd_set key_rfd;
 fd=open(DEV_NAME,O_RDWR);
 printf("fd=%d\n",fd);
 if(fd<0)
 {
  perror("error open\n");
  exit(-1);
 }
 printf("open /dev/key successfully\n");
 while(1)
 {
  read(fd,&key,sizeof(int));
  if(0==key)
   continue;
  printf("get key:sw%d\n",key);
 }
 return 0;
}

/*****************************************************************

应用程序key_poll查询模式测试源代码:

*****************************************************************/

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MYKEY "/dev/key_driver"
#define KEY1 1
#define KEY2 2
#define KEY3 3
#define KEY4 4
#define KEY5 5
#define KEY6 6
#define NOKEY 0
int fd;

void Delay_MS( unsigned int time)  //50 ns
{
 unsigned int i,j;
 
 for ( i=0; i<time; i++)
 {
    for(j=0;j<30000;j++)
    {
   
    } 
  } 
}


//函数:KeyScan
//功能:读取按下的按键,并返回按键的标记号
//参数:无
//返回值:int
int  KeyScan(void)
{
 volatile unsigned int temp,status; 
 int key=NOKEY; //记录press 的按键

 /*注意:GPGDAT先取反,press后GPGDAT原来为0,取反后为1*/
 /*再& ,取出到底是哪一位按下,按下的为1*/
 read(fd,&status,4);
 temp = (~status ) & ((1<<11)|(1<<7)|(1<<6)|(1<<5)|(1<<3)|(1<<0));
 
 switch(temp)
 {
  case (1<<0):  //KEY1
  { 
   key = KEY1;
   return key;
  }
  case (1<<3):  //KEY2
  { 
   key = KEY2;
   return key;
  }
  case (1<<5):  //KEY3
  { 
   key = KEY3;
   return key;
  }
  case (1<<6):  //KEY4
  {
   key = KEY4;
   return key;
  }
  case (1<<7):  //KEY5
  {
   key = KEY5;
   return key;
  }
  case (1<<11):  //KEY6
  {
   key = KEY6;
   return key;
  }
  default:   //NOKEY
   return NOKEY;
 }
}


volatile unsigned int key_old=NOKEY;
volatile unsigned int key_new=NOKEY;
int Get_Keyvalue(void)
{
 int key_1=NOKEY;
 int key_2=NOKEY;

 
 key_1=KeyScan();
 Delay_MS(20);
 key_2=KeyScan();
 if(key_1 != key_2)   //如果按下的key_1和key_2不相等,说明抖动
 {
  return NOKEY; //就当作没按下
 }
 else   //如果按下的key_1和key_2相等,说明按住不放,重复
 {
  key_new=key_2;
  if(key_new!=key_old)  //按下的跟之前那次比较,如果新按的跟旧按下的不相等
  {
   key_old=key_new; //旧值更新
   return key_old;  //返回有按下
  }
  else if(key_new==key_old) //如果新按的跟旧按下的相等
  {
   return NOKEY;  //就当作没按下
  }
 }
 
}


int main()
{
 int i=0;
 unsigned int cmd;
 unsigned int status;
 int key;
 int g_led_num;
 volatile unsigned int temp;
     fd = open(MYKEY,O_RDWR);
 if (fd < 0)
 {
  perror("open device key_driver----");
  exit(1);
 }
 while(1)
 {
  
  
  key = Get_Keyvalue();
  if(key==1)
  {
   printf("********1**********\n");
  }
  if(key==2)
  {
   printf("********2**********\n");
  }
  if(key==3)
  {
   printf("********3**********\n");
  }
  if(key==4)
  {
   printf("********4**********\n");
  }
  if(key==5)
  {
   printf("********5**********\n");
  }
  if(key==6)
  {
   printf("*********6**********\n");
  }
 }
 close(fd)
}

 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值