2010年12月8日 星期三

Linux Kernel時序的機制

寫Driver時,常常遇到需要「等待一段時間」再處理的動作。
這時候,Timer 就是使用的好時機。

add_timer的使用方法

首先你要申請一個timer struct:
static struct timer_list timer;
或是用pointer申請
static struct timer_list *timer;

在第一次使用時一定要初始化:
init_timer(&timer);
設定要傳的data
timer.data = (unsigned long )foo_data;
設定間隔時間
timer.expires = jiffies + DELAY_TIME;
設定timer到時要跑的function
timer.function = foo_function;

接著把這個timer加進timer list結構
add_timer(&timer);

時間到了就會去執行程式foo_function,
但是從此timer就停了。必須重新add_timer才會在下一次繼續啟動

在離開時,記得要
deltimer(&timer);

int mod_timer(struct timer_list *timer, unsigned long expires);
//修改定時器的expire
int timer_pending(const struct timer_list * timer);
//返回真或假來指示是否定時器已被運行



底下是我用來點亮 LED,然後過一段時間,自己滅掉 LED 的程式例子。

typedef struct blk_led_s
{
     int cBlinking;
     struct timer_list blinkled_timer;
}blk_led_t;
static blk_led_t gEthLed;

static void hdd_led_on(void)
{
    gEthLed.cBlinking = 1;
    gEthLed.blinkled_timer.expires = jiffies + HZ/5;
    add_timer(&gEthLed.blinkled_timer);

    LED_on();
}

static void hdd_led_off(unsigned long data)
{
    LED_on();
    gEthLed.cBlinking = 0;
}

int __init init_timer(void)
{
    // printk(">>>>>>>>>> init HDD LED timer\n");
    gEthLed.cBlinking=0;
    // Timer 初始化
    init_timer(&gEthLed.blinkled_timer);
    // 定義 timer 所執行之函式
    gEthLed.blinkled_timer.function = &hdd_led_off;
    // 定義 timer 傳入函式之 Data
    gEthLed.blinkled_timer.data = (0);
    // 定義 timer Delay 時間
    gEthLed.blinkled_timer.expires = jiffies + HZ/10;
    // 啟動 Timer
    add_timer(&gEthLed.blinkled_timer);

    return 0;
}


reference:
http://blog.wu-boy.com/2010/07/kernel-driver-%E6%92%B0%E5%AF%AB%E7%B0%A1%E6%98%93-timer-%E6%A9%9F%E5%88%B6/
http://nano-chicken.blogspot.com/2009/12/linux-modules71-timer.html


沒有留言:

張貼留言