怎么使用pcDuino的外部中断

本篇文章给大家分享的是有关怎么使用pcDuino的外部中断,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

宝山网站制作公司哪家好,找成都创新互联!从网页设计、网站建设、微信开发、APP开发、自适应网站建设等网站项目制作,到程序开发,运营维护。成都创新互联成立与2013年到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联

按键中断—poll机制

我们尝试让按键具有这样一种功能,如果一定的时间内没有人去按按键,内核就提醒一下,然后我们应用程序得到提醒之后打印time out。

驱动程序      

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define GPIO_IRQ  28

#define GPIO_TEST_BASE 0xf1c20800

#define PH_CFG2                     (GPIO_TEST_BASE + 0x104)

#define PIO_INT_CFG2    (GPIO_TEST_BASE+ 0x208)

#define PIO_INT_CTL                (GPIO_TEST_BASE+ 0x210)

#define PH17_SELECT (6 << 4)

#define PH18_SELECT (6 << 8)

#define PH19_SELECT (6 << 12)

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

/* 中断事件标志, 中断服务程序将它置1,third_drv_read将它清0 */

static volatile int ev_press = 0;

static struct class *keydrv_class;

static unsigned int status;

static irqreturn_t key_irq(int irq, void *dev_id)

{

         status =readl(GPIO_TEST_BASE + 0x214 ) ;

         ev_press = 1;                  /* 表示中断发生了 */

             wake_up_interruptible(&button_waitq);   /* 唤醒休眠的进程 */

         writel(status,GPIO_TEST_BASE + 0x214);      

         return IRQ_HANDLED;

}

static int key_drv_open(struct inode *inode, struct file *file)

{

         int error;

         int irq_ctl;

         /*1,设置中断位*/

         irq_ctl =readl(PH_CFG2);

         writel(PH19_SELECT|PH17_SELECT|PH18_SELECT| irq_ctl ,PH_CFG2);

         /*2,设置中断方式*/

         irq_ctl =readl(PIO_INT_CFG2);

         writel((0x4<<(1*4))|(0x4 <<(2*4))|(0x4 <<(3*4)) | irq_ctl,PIO_INT_CFG2);

         /*3,开中断*/        

         irq_ctl =readl(PIO_INT_CTL);

         writel((0xf <<16)|irq_ctl,PIO_INT_CTL);

         error =request_irq(GPIO_IRQ, key_irq,0, "button", 1);

    if (error) {

        printk("failed toregister keypad interrupt\n");

    }

         printk(KERN_ALERT"keyopeni\n");

         return 0;

}

static unsigned key_drv_poll(struct file *file, poll_table *wait)

{

         unsigned int mask = 0;

         poll_wait(file,&button_waitq, wait); // 不会立即休眠

         if (ev_press)

                   mask |=POLLIN | POLLRDNORM;

         return mask;

}

ssize_t key_drv_read(struct file *file, char __user *buf, size_tsize, loff_t *ppos)

{

         /* 如果没有按键动作, 休眠 */

         wait_event_interruptible(button_waitq,ev_press);

         /* 如果有按键动作, 返回键值 */

         copy_to_user(buf,&status, sizeof(unsigned int));

         ev_press = 0;

         return 1;

}

static ssize_t key_drv_write(struct file *file, const char __user*buf, size_t count, loff_t * ppos)

{

         printk(KERN_ALERT"keywrite\n");

         return 0;

}

int key_drv_close(struct inode *inode, struct file *file)

{

         free_irq(GPIO_IRQ,1);

         return 0;

}

static struct file_operations key_drv_fops = {

    .owner  =  THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

    .open   =  key_drv_open,     

    .write  =          key_drv_write,         

    .read   =       key_drv_read,

         .release =  key_drv_close,

         .poll    = key_drv_poll,

};

int major;

static int key_drv_init(void)

{        

         major =register_chrdev(0, "key_drv", &key_drv_fops);

         keydrv_class =class_create(THIS_MODULE,"key_drv");

         device_create(keydrv_class,NULL,MKDEV(major,0),NULL,"key");

         printk(KERN_ALERT"register\n");

         return 0;

}

static void key_drv_exit(void)

{

         unregister_chrdev(major,"key_drv"); // 卸载

         device_destroy(keydrv_class,MKDEV(major,0));

         class_destroy(keydrv_class);

         printk(KERN_ALERT"unregister\n");

}

module_init(key_drv_init);

module_exit(key_drv_exit);

MODULE_LICENSE("GPL");

测试程序     test_key.c (706 Bytes, 下载次数: 0, 售价: 5 金钱) :

#include

#include

#include

         int kbit = 0;

void PrintBinary(unsigned int c)

{

    if (c>>1)PrintBinary(c>>1);

    printf("%d:%d",kbit, c&1);

         kbit++;

}

int main()

{

         int fd;

         unsigned int val = 1;

         int ret;

         struct pollfd fds[1];

         fd =open("/dev/key",0666);

         if(fd < 0)

         {

                   printf("cannotopen\n");

                   return 0;

         }

         fds[0].fd     = fd;

         fds[0].events =POLLIN;

         while(1)

         {

                   kbit = 0;

                   ret =poll(fds, 1, 5000);

                   if (ret ==0)

                   {

                            printf("timeout\n");

                   }

                   else

                   {

                            read(fd,&val,sizeof(unsignedint));

                            PrintBinary(val);

                            if(val&(1<<17))printf("Back\n");

                            if(val&(1<<18))printf("home\n");

                            if(val&(1<<19))printf("menu\n");

                   }

         }

         close(fd);

         return 0;

}

编译:

gcc test_key.c

测试:

root @ubuntu :/home/ubuntu/driver/key_02# ./a.out

[10049.740000] key openi

0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 18:0 home

0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 18:0 home

time out

time out

time out

time out

0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 Back

0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 Back

以上就是怎么使用pcDuino的外部中断,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。


名称栏目:怎么使用pcDuino的外部中断
当前链接:http://pwwzsj.com/article/jjjoop.html