深入浅出LDD-8-定时器1-机制

/***************************************************************************************************
                                    设备驱动中的定时器--机制篇
编译环境:不需要
实 验 者:张永辉 2012年9月13日
***************************************************************************************************/
    Linux 内核中定义了一个 timer_list 结构,我们在驱动程序中可以利用之:
        struct timer_list
        {
            struct list_head list;
            unsigned long expires;      //定时器到期时间
            unsigned long data;         //作为参数被传入定时器处理函数
            void (*function)(unsigned long);
        };

    下面是关于 timer 的 API 函数:
        void add_timer(struct timer_list * timer);      //增加定时器
        int  del_timer(struct timer_list * timer);
        int mod_timer (struct timer_list *timer, unsigned long expires); //修改定时器的 expire

    使用定时器的一般流程为:
        (1)timer、编写 function;
        (2)为 timer 的 expires、data、function 赋值;
        (3)调用 add_timer 将 timer 加入列表;
        (4)在定时器到期时,function 被执行;
        (5)在程序中涉及 timer 控制的地方适当地调用 del_timer、mod_timer 删除 timer 或修改 timer 的 expires。

实例:
drivers\char\keyboard.c 中键盘的驱动中关于 timer 的部分:

#include <linux/timer.h>

static struct timer_list key_autorepeat_timer =
{
    function: key_callback
};

static void kbd_processkeycode(unsigned char keycode, char up_flag, int autorepeat)
{
    char raw_mode = (kbd->kbdmode == VC_RAW);

    if (up_flag)
    {
        rep = 0;
        if(!test_and_clear_bit(keycode, key_down))
            up_flag = kbd_unexpected_up(keycode);
    }else
    {
        rep = test_and_set_bit(keycode, key_down);
        /* If the keyboard autorepeated for us, ignore it.
        * We do our own autorepeat processing.*/
    if (rep && !autorepeat)
        return;
    }

    if (kbd_repeatkeycode == keycode || !up_flag || raw_mode)
    {
        kbd_repeatkeycode = -1;
        del_timer(&key_autorepeat_timer);
    }
    ...
    /** Calculate the next time when we have to do some autorepeat
    * processing.    Note that we do not do autorepeat processing
    * while in raw mode but we do do autorepeat processing in
    * medium raw mode.   */
    if (!up_flag && !raw_mode)
    {
        kbd_repeatkeycode = keycode;
        if (vc_kbd_mode(kbd, VC_REPEAT))
        {
            if (rep)
                key_autorepeat_timer.expires = jiffies + kbd_repeatinterval;
            else
                key_autorepeat_timer.expires = jiffies + kbd_repeattimeout;
            add_timer(&key_autorepeat_timer);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值