arm驱动程序——按键程序2(韦东山的视频总结及针对linux-2.6.30)

http://www.ithao123.cn/content-848618.html

相关代码在资源中下载。

用到的结构及,函数及其他:

/*用于产生一个等待队列的头文件,定义在wait.h中*/

#define DECLARE_WAIT_QUEUE_HEAD(name)
       wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)

/*pin;所要获取的引脚*/

unsigned int s3c2410_gpio_getpin(unsigned int pin);

/*用于中断唤醒的,x:等待队列的头文件*/

#define wake_up_interruptible(x)   __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)

/*休眠,直到条件满足,wq:等待队列的头文件,condition:条件为真时,会被唤醒,假时休眠,

 *在中断处理函数时,condition复制为1

 */

#define wait_event_interruptible(wq, condition)
( {
      int __ret = 0;
      if (!(condition))
         __wait_event_interruptible(wq, condition, __ret);
      __ret;
})

驱动程序:

#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <mach/irqs.h>
#include <mach/regs-gpio.h>
/*不同的linux内核,头文件会有所不同*/


static unsigned long major;
static struct class *second_key_class;
static struct device *second_key_device;
static volatile int en_press = 0;

static int key_val;

/*产生一个等待队列的头文件*/

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

/*定义一个引脚描述结构体*/
struct pindec{
    unsigned long pin;
    unsigned long val;
};


/*松开按键的值为0x01,0x02,0x3,0x04*/
/*按下按键时值为0x81,0x82,0x83,0x84*/
struct pindec pin_dec[4] = {
   {S3C2410_GPF0,0x04},
   {S3C2410_GPF1,0x01},
   {S3C2410_GPF2,0x03},
   {S3C2410_GPF4,0x02},
};


/*中断处理函数*/
static irqreturn_t buttons_irq(int irq,void *dev_id)
{

     struct pindec *pindesc = (struct pindec *)dev_id;

        /*获得引脚状态*/

     unsigned long pinval = s3c2410_gpio_getpin(pindesc->pin);

        /*如何按下按键,pinval =0,*/

     if(pinval)
         key_val  = pindesc->val;
     else
         key_val = pindesc->val|0x80;

     en_press = 1;

        /*唤醒中断*/

     wake_up_interruptible(&button_waitq);
     return IRQ_RETVAL(IRQ_HANDLED);

}


static int second_key_open(struct inode *inode, struct file *file)
{
     /*注册中断*/
     request_irq(IRQ_EINT1,buttons_irq,IRQ_TYPE_EDGE_BOTH,"s1",&pin_dec[1]);
     request_irq(IRQ_EINT4,buttons_irq,IRQ_TYPE_EDGE_BOTH,"s2",&pin_dec[3]);
     request_irq(IRQ_EINT2,buttons_irq,IRQ_TYPE_EDGE_BOTH,"s3",&pin_dec[2]);
     request_irq(IRQ_EINT0,buttons_irq,IRQ_TYPE_EDGE_BOTH,"s4",&pin_dec[0]);
     return 0;
}
static int second_key_close(struct inode *inode, struct file *file)

{

         /*释放定义的request_irq*/

   free_irq(IRQ_EINT1,&pin_dec[1]);
   free_irq(IRQ_EINT4,&pin_dec[3]);
   free_irq(IRQ_EINT2,&pin_dec[2]);
   free_irq(IRQ_EINT0,&pin_dec[0]);
   return 0;
}
static ssize_t second_key_read(struct file *file, char __user *user_buffer, 
   size_t count, loff_t *ppos)
{

    if(count != 1)
        return -EINVAL;
   /*松开按键时,进入休眠,当中断发生时,调用中断处理函数进行唤醒*/
    wait_event_interruptible(button_waitq,en_press);
    /*按下按键时,传数据给用户空间*/
    copy_to_user(user_buffer,&key_val,1);
    en_press = 0;
    return 1;
}
/*定义一个file_operations结构*/

static struct file_operations secong_key_fops {

      .owner = THIS_MODULE,

      .open  = second_key_open,
      .read  = second_key_read,
      .release = second_key_close,      
      };
/*入口函数*/  
static int second_key_init(void)
{
    /*注册*/
    major = register_chrdev(0,"second_buttons",&secong_key_fops);
    /*创建类*/
    second_key_class = class_create(THIS_MODULE,"second_class");
   /*创建设备*/
    second_key_device =
    device_create(second_key_class,NULL,MKDEV(major,0),NULL,"second_device");
    return 0;
}
/*出口函数*/
static void second_key_exit(void)

{

    /*注销*/

    unregister_chrdev(major,"second_buttons");

   /*注销设备*/

   device_unregister(second_key_device);

   /*销毁定义的类*/

   class_destroy(second_key_class);

}

/*修饰*/

module_init(second_key_init);
module_exit(second_key_exit);
MODULE_LICENSE("GPL");


测试程序:

#include<stdio.h>

#include<fcntl.h>
#include<unistd.h>
void main(int argc,char **argv)
{
unsigned long key_val;
int fd;
fd = open("/dev/second_device",O_RDWR);
if(fd < 0)
printf("can't open!");
while(1)
{
read(fd,&key_val,1);
printf("key_val = 0x%xn",key_val);
}
}

测试就很简单了:

1.加载驱动程序:

2.执行应用程序;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值