liunx驱动----系统滴答时钟的使用

2019-3-12系统滴答定时器中断使用

  1. 定义一个timer

其实就是使用系统的滴答定时器产生一个中断。

  1. 初始化timer
  2.   init_timer函数 实现如下
void fastcall init_timer(struct timer_list *timer)
{
timer->entry.next = NULL;
timer->base = __raw_get_cpu_var(tvec_bases);
ifdef CONFIG_TIMER_STATS
timer->start_site = NULL;
timer->start_pid = -1;
memset(timer->start_comm, 0, TASK_COMM_LEN);
endif
}
EXPORT_SYMBOL(init_timer);

 

 
liunx驱动----系统滴答时钟的使用_第1张图片
liunx驱动----系统滴答时钟的使用_第2张图片
从这个结构的内容中可以看出,必须要设置 entry:链表相关 expires:保存超时时间 function :指向当超时事件发生后进入那个处理函数 data:需要传递给这个函数的参数 *base :保存当前的基地址
  1. 在按键中断中修改 超时时间

 

liunx驱动----系统滴答时钟的使用_第3张图片
 

 

liunx驱动----系统滴答时钟的使用_第4张图片

jiffies :当前系统滴答值 HZ:默认为100 10ms一个节拍
 
 
 
实现功能:当按键中断发生后等待10ms后才去处理,获取到的值。
初始化函数:
static int sixth_drv_init(void)
{

    /*初始化  timer  定义的这个软件定时器*/  
    init_timer(&buttons_timer);
    buttons_timer.function = buttons_timer_function;
    add_timer(&buttons_timer);//告诉内核有这样一个定时器
    
    major = register_chrdev(0, "sixth_drv", &sencod_drv_fops);

    sixthdrv_class = class_create(THIS_MODULE, "sixth_drv");

    sixthdrv_class_dev = class_device_create(sixthdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */

    gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
    gpfdat = gpfcon + 1;

    gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);
    gpgdat = gpgcon + 1;

    return 0;
}

按键中断处理函数:

static irqreturn_t buttons_irq(int irq, void *dev_id)
{
    irq_pd = (struct pin_desc *)dev_id;
    //修改定时器的超时时间  HZ = 100  jiffies 当前时钟  10ms后进入中断处理函数
    mod_timer(&buttons_timer, jiffies+HZ/100);//jiffies  是一个全局变量  系统每隔10ms就会产生一个系统时钟中断 过100个10ms进入中断  
    return IRQ_RETVAL(IRQ_HANDLED);
}

超时事件处理函数:

static void buttons_timer_function(unsigned long data)
{
    
    struct pin_desc * pindesc = irq_pd;
    unsigned int pinval;
    if(!pinval)return ;//如果为空直接返回0
    pinval = s3c2410_gpio_getpin(pindesc->pin);

    if (pinval)
    {
        /* 松开 */
        key_val = 0x80 | pindesc->key_val;
    }
    else
    {
        /* 按下 */
        key_val = pindesc->key_val;
    }

    ev_press = 1;                   /* 表示中断发生了 */
    wake_up_interruptible(&button_waitq);    /* 唤醒休眠的进程 */

    kill_fasync (&button_async, SIGIO, POLL_IN);
}

 

转载于:https://www.cnblogs.com/hjxzjp/p/10520031.html

你可能感兴趣的:(liunx驱动----系统滴答时钟的使用)