有时候并不想tasklet在硬件中断接受后立刻执行,可以在中断中使用tasklet_hrtimer_init函数
void tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer,
enum hrtimer_restart (*function)(struct hrtimer *),
clockid_t which_clock, enum hrtimer_mode mode)
{
hrtimer_init(&ttimer->timer, which_clock, mode);
ttimer->timer.function = __hrtimer_tasklet_trampoline;
tasklet_init(&ttimer->tasklet, __tasklet_hrtimer_trampoline,
(unsigned long)ttimer);
ttimer->function = function;
}
这个函数主要做了两件事情,首先注册了一个time,然后在timer到期后的callback函数是__hrtimer_tasklet_trampoline。
其次初始化一个tasklet_init,这个tasklet的回调函数是__tasklet_hrtimer_trampoline。
static enum hrtimer_restart __hrtimer_tasklet_trampoline(struct hrtimer *timer)
{
struct tasklet_hrtimer *ttimer =
container_of(timer, struct tasklet_hrtimer, timer);
tasklet_hi_schedule(&ttimer->tasklet);
return HRTIMER_NORESTART;
}
这个又调用tasklet的回调函数__tasklet_hrtimer_trampoline
static void __tasklet_hrtimer_trampoline(unsigned long data)
{
struct tasklet_hrtimer *ttimer = (void *)data;
enum hrtimer_restart restart;
restart = ttimer->function(&ttimer->timer);
if (restart != HRTIMER_NORESTART)
hrtimer_restart(&ttimer->timer);
}
而tasklet的回调函数就调用用户注册的callback函数 ttimer->function(&ttimer->timer);
下面举个实用的例子
注册:
tasklet_hrtimer_init(&data->beacon_timer,
mac80211_hwsim_beacon,
CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
开始:
其中next_bcn
next_bcn = ktime_add(hrtimer_get_expires(timer),
ns_to_ktime(bcn_int * 1000));
tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS);
取消:
tasklet_hrtimer_cancel(&data->beacon_timer);
void tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer,
enum hrtimer_restart (*function)(struct hrtimer *),
clockid_t which_clock, enum hrtimer_mode mode)
{
hrtimer_init(&ttimer->timer, which_clock, mode);
ttimer->timer.function = __hrtimer_tasklet_trampoline;
tasklet_init(&ttimer->tasklet, __tasklet_hrtimer_trampoline,
(unsigned long)ttimer);
ttimer->function = function;
}
这个函数主要做了两件事情,首先注册了一个time,然后在timer到期后的callback函数是__hrtimer_tasklet_trampoline。
其次初始化一个tasklet_init,这个tasklet的回调函数是__tasklet_hrtimer_trampoline。
static enum hrtimer_restart __hrtimer_tasklet_trampoline(struct hrtimer *timer)
{
struct tasklet_hrtimer *ttimer =
container_of(timer, struct tasklet_hrtimer, timer);
tasklet_hi_schedule(&ttimer->tasklet);
return HRTIMER_NORESTART;
}
这个又调用tasklet的回调函数__tasklet_hrtimer_trampoline
static void __tasklet_hrtimer_trampoline(unsigned long data)
{
struct tasklet_hrtimer *ttimer = (void *)data;
enum hrtimer_restart restart;
restart = ttimer->function(&ttimer->timer);
if (restart != HRTIMER_NORESTART)
hrtimer_restart(&ttimer->timer);
}
而tasklet的回调函数就调用用户注册的callback函数 ttimer->function(&ttimer->timer);
下面举个实用的例子
注册:
tasklet_hrtimer_init(&data->beacon_timer,
mac80211_hwsim_beacon,
CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
开始:
其中next_bcn
next_bcn = ktime_add(hrtimer_get_expires(timer),
ns_to_ktime(bcn_int * 1000));
tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS);
取消:
tasklet_hrtimer_cancel(&data->beacon_timer);