8

私の目標は、構造体を使用して Linux カーネルで繰り返しタスクを作成することhrtimerです。500ミリ秒ごとに繰り返したいと思います。

hrtimerしかし、 Linux カーネルで がどのように機能するかについては、少し混乱しています (「参考文献」を参照linux/hrtimer.h)。HRTIMER_RESTART時間が指定されていることはわかっており、コールバックはまたはを返す必要がありますHRTIMER_NORESTART。メソッドを使用してコールバックでタイマーをリセットする必要があると述べているオンラインのソースをいくつか見つけましたhrtimer_forward。ただし、私が見た情報源は、時間の追加がどのように機能するかについて少し不明確です。これまでのコードは次のとおりです。

static struct hrtimer timer;

static enum hrtimer_restart timer_callback(struct hrtimer *timer)
{
    printk(KERN_ERR "Callback\n");
    //I know something needs to go here to reset the timer
    return HRTIMER_RESTART;
}

static int init_timer(void)
{   
    ktime_t ktime;
    unsigned long delay_in_ms = 500L;
    printk(KERN_ERR "Timer being set up\n");

    ktime = ktime_set(0,delay_in_ms*1E6L);
    hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);

    timer.function = &timer_callback;
    printk(KERN_ERR "Timer starting to fire\n");
    printk(KERN_ERR "in %ldms %ld\n", delay_in_ms, jiffies);

    hrtimer_start(&timer, ktime, HRTIMER_MODE_REL);
    return 0;
}

static void clean_load_balancing_timer(void)
{
    int cancelled = hrtimer_cancel(&timer);

    if (cancelled)
        printk(KERN_ERR "Timer still running\n");
    else
        printk(KERN_ERR "Timer cancelled\n");
}

タイマーのリセットがコールバック関数でどのように機能するかを誰かが正確に説明できますか? ありがとう!

4

2 に答える 2

9

関数 sched_rt_period_timer の 170 行付近で kernel/sched.c を見ると、使用例が表示されます。本質的な行は

now = hrtimer_cb_get_time(timer);                               
overrun = hrtimer_forward(timer, now, rt_b->rt_period);

ここで、タイマーの現在の時刻を ktime_t として取得し、rt_b->rt_period は、タイマーを進める期間を指定する別の ktime_t です。hrtimer の有効期限は、現在の時刻よりも大きくなるまで、期間によって継続的に増分されます。現在の時刻よりも長い有効期限を取得するために期間の追加が複数回行われた場合、戻り値は 1 よりも大きくなります (オーバーランが多いことを示します)。タイマーの有効期限がまったく進まなかった場合は、ゼロになる可能性があります。

参考: http: //lwn.net/Articles/167897/

使用する API は異なるバージョンのカーネルのものであるため、一部の引数が変更されています。基本的な考え方は今でも同じです。

于 2012-11-04T00:31:38.310 に答える