跳转至

08 定时器实验

笔记说明

定时器这一部分主要需要注意的,和韦东山他们教程,有差异的就是,我使用的6.6内核,只支持新的定时器初始化函数。不支持他们教程中比较老的函数。主要功能就是注册了一个定时器,然后在中断调用的时候触发这个定时器,使得按键消抖。

主要参考的文章

正点原子《I.MX6U 嵌入式 Linux 驱动开发指南 V1.81》

韦东山《01_嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板》

本节源码路径02_Firmware/08_key_drv_irq_timer

驱动编写

定时器使用完了后需要注销。

static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{
    key_gpio_t *gpio_key = dev_id;
    printk("%s %s line %d\r\n", __FILE__, __FUNCTION__, __LINE__);

    mod_timer(&gpio_key->key_timer, jiffies + HZ/10);    
    return IRQ_RETVAL(IRQ_HANDLED);
}

static void key_timer_expire(struct timer_list *t)
{
    key_gpio_t *gpio_key = from_timer(gpio_key, t, key_timer);
    int val;
    printk("%s %s line %d\r\n", __FILE__, __FUNCTION__, __LINE__);
    val = gpiod_get_value(gpio_key->key_gpiod);
    printk("key %d %d\n", gpio_key->key_num, val);      
}

static int key_probe(struct platform_device *dev)
{  
    int ret;
    // 中断相关的初始化
    // ************** //

    for(int i=0 ; i < 3; i++){
        timer_setup(&key_dev.key_gpio[i].key_timer, key_timer_expire, 0);
        key_dev.key_gpio[i].key_timer.expires = ~0;
        add_timer(&key_dev.key_gpio[i].key_timer);
    }

    // 注册misc字符设备驱动
    // ************** //
    return 0;
}

static int key_remove(struct platform_device *dev)
{
    // 释放gpio
    // ************** //

    for (int i = 0; i < 3; i++)
    {
        free_irq(key_dev.key_gpio[i].key_irq, &key_dev.key_gpio[i]);
        del_timer(&key_dev.key_gpio[i].key_timer);
    }
    /* 注销misc设备 */
    misc_deregister(&key_miscdev);
    return 0;
}