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成功:

  • 相关阅读:
    PerfDog携手Imagination,助力开发者获取GPU关键数据
    WeTest云手机升级,支持iOS 15全新系统
    洞穿性能测试痛点,PerfDog以提升应用和游戏的品质为使命
    使用xmlhttprequest遇到CORS报错的处理
    Hive的联级(cascade)-新增字段(column)后,旧分区无法更新数据问题
    数据异常检测入门
    Linux查看文件或文件夹大小: du命令
    k8s pod自动重启原因(jvm内存设置)
    计算容器运行至今多长时间
    期刊论文在线投稿审稿系统day1数据库设计
  • 原文地址:https://www.cnblogs.com/FORFISH/p/5188564.html
Copyright © 2011-2022 走看看