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;
}