zoukankan      html  css  js  c++  java
  • 7.阻塞型驱动设计

    阻塞型驱动设计

    唤醒之后按优先级执行。

    对按键驱动进行阻塞型改造

    改造的duokey.c:

    Make会产生一下的问题还没解决,由于没有网络。差个头文件.....

    明天有网络再说咯

    找到了头文件,linux/sched.h又出现了奇怪的错误:

    很奇怪,是重名。可我没有定义key..h,是系统的。最后改为button_init和button_exit.make通过了。

    Duokey.c的代码:

    #include <linux/module.h>        /* For module specific items */

    #include <linux/fs.h>            /* For file operations */

    #include <linux/ioport.h>        /* For io-port access */

    #include <linux/io.h>            /* For inb/outb/... */

    #include <linux/init.h>

    #include <linux/miscdevice.h>

    #include <linux/interrupt.h>

    #include <linux/slab.h>

    #include <linux/uaccess.h>

    #include <linux/sched.h>

    #define TASK_UNINTERRUPTIBLE    2

    #define TASK_INTERRUPTIBLE    1

    #define TASK_NORMAL        (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)

    #define GPNCON 0x7f008830

    #define GPNDAT 0x7f008834

    struct work_struct *work1;

    struct timer_list key_timer;//定义定时器

    unsigned int *gpio_data;

    //全局变量,初始化为0

    unsigned int key_num =0 ;

    //定义等待队列

    wait_queue_head_t key_q;

    //read按键

    ssize_t key_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)

    {

        wait_event(key_q,key_num);

        printk("<0> in kernel:key num is%d ",key_num);

        //返回内核的给用户

        copy_to_user(buf,&key_num,4);

        key_num=0;//清空按键

        return 4;

    }

    void work1_func(struct work_struct *work)

    {

        //启动定时器 100毫秒超时=HZ/10,HZ=1秒。jiffies是系统当前时间

        mod_timer(&key_timer,jiffies+HZ/10);

    }

    void key_timer_func(unsigned long data)

    {    //定时器超时的函数需要修改,需要判断是哪个按键超时

        

        unsigned int key_val;

        //超时的时候,就要读取data

        key_val=readw(gpio_data)&0x01;//读出一个按键EINT0的值。

        //当他被按下,就是低电平的时候,就是被按下了。才是有效的按键

        if(0==key_val)//真正按下

            key_num=1;//读取按键编号

        key_val=readw(gpio_data)&0x02;//读出一个按键EINT1的值。

        //当他被按下,就是低电平的时候,就是被按下了。才是有效的按键

        if(0==key_val)//真正按下

            key_num=2;

        

        //当有数据的时候,需要唤醒

        wake_up(&key_q);

    }

    irqreturn_t key_int(int irq, void *dev_id)

    {

        //1.检测是否发生了按键中断

        //2.清除已经发生的按键中断

    //前面的都是硬件相关的工作,必须在中断里面执行

    //下面是硬件无关的工作,我们把它提到中断以外的work1_func函数去处理。

        //3.打印按键值

        schedule_work(work1);

        

        return 0;

    }

    void key_hw_init()

    {

        unsigned int *gpio_config;

        unsigned short data;

        gpio_config = ioremap(GPNCON,4);

        data = readw(gpio_config);

        data &= ~0b1111;//增加一个按键

        data |= 0b1010;

        writew(data,gpio_config);

        gpio_data = ioremap(GPNDAT,4);

    }

    int key_open(struct inode *node, struct file *filp)

    {

        return 0;

    }

    struct file_operations key_fops =

    {

        .open = key_open,

        .read = key_read,//增加了读取操作

    };

    struct miscdevice key_miscdevice =

    {

        .minor = 200,

        .name = "6410key",

        .fops = &key_fops,

    };

    static int button_init()

    {

        misc_register(&key_miscdevice);

        //注册中断处理程序

        request_irq(IRQ_EINT(0),key_int, IRQF_TRIGGER_FALLING,"6410key",0);

        //增加一个按键的支持

        request_irq(IRQ_EINT(1),key_int, IRQF_TRIGGER_FALLING,"6410key",0);

        

        //硬件初始化

        key_hw_init();//相应的位进行设置

        //2. 创建工作

        work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);

        INIT_WORK(work1, work1_func);

        //定时器初始化

        init_timer(&key_timer);

        key_timer.function=key_timer_func;

        

        //注册定时器

        add_timer(&key_timer);

        //初始化等待队列

        init_waitqueue_head(&key_q);

        return 0;

    }

    static void button_exit()

    {

        misc_deregister(&key_miscdevice);

        

    }

    module_init(button_init);

    module_exit(button_exit);

    /*优化:多一个中断,gpio也进行多按键初始化,中断产生的时候要判断是哪个按键产生的中断。*/

    Make成功:

  • 相关阅读:
    商贸通帐套隐藏方法
    固定资产打开提示:上年度数据未结转!
    ZOJ 2432 Greatest Common Increasing Subsequence
    POJ 1080 Human Gene Functions
    POJ 1088 滑雪
    POJ 1141 Brackets Sequence
    POJ 1050 To the Max
    HDOJ 1029 Ignatius and the Princess IV
    POJ 2247 Humble Numbers
    HDOJ 1181 变形课
  • 原文地址:https://www.cnblogs.com/FORFISH/p/5188564.html
Copyright © 2011-2022 走看看