//创建一个软件定时器
static struct timer_list my_timer;//定义一个软件定时器
struct timer_list {
struct list_head entry; //定时器链表的入口
unsigned long expires; //定时器超时时的节拍数
void (*function)(unsigned long); //【重要】定时器处理函数
unsigned long data; //传给定时器处理函数的长整型参数
struct tvec_t_base_s *base; //定时器内部值,用户不使用
#ifdef CONFIG_TIMER_STATS
void *start_site;
char start_comm[16];
int start_pid;
#endif
};
void my_timer_function(...);//定义自己的软件定时器函数
init_timer(&my_timer);
my_timer.function=my_timer_function;
add_timer(my_timer);
//获得当前系统内核的时间,该时间是距离1970年1月1日0时0分0秒的时间,用秒和纳秒表示
//timespec里面是秒和纳秒
struct timespec current_kernel_time(void)
{
struct timekeeper *tk = &tk_core.timekeeper;
struct timespec64 now;
unsigned long seq;
do {
seq = read_seqcount_begin(&tk_core.seq);
now = tk_xtime(tk);
} while (read_seqcount_retry(&tk_core.seq, seq));
return timespec64_to_timespec(now);
}
//用于将非活跃状态的定时器从动态定时器链表中删除
//返回1说明删除成功,返回0说明定时器正在执行或已经不存在,删除无效
int del_timer(struct timer_list *timer);
//获取当前系统内核时间,保存再tv结构体中,距离1970.1.1 00:00:00的秒差
void do_gettimeofday(struct timeval *tv)
{
struct timespec64 now;
getnstimeofday64(&now);
tv->tv_sec = now.tv_sec;
tv->tv_usec = now.tv_nsec/1000;
}
//设定系统内核时间,设定为 ts 所代表的时间,距离1970的秒数
int do_settimeofday64(const struct timespec64 *ts)
{
struct timekeeper *tk = &tk_core.timekeeper;
struct timespec64 ts_delta, xt;
unsigned long flags;
if (!timespec64_valid_strict(ts))
return -EINVAL;
raw_spin_lock_irqsave(&timekeeper_lock, flags);
write_seqcount_begin(&tk_core.seq);
timekeeping_forward_now(tk);
xt = tk_xtime(tk);
ts_delta.tv_sec = ts->tv_sec - xt.tv_sec;
ts_delta.tv_nsec = ts->tv_nsec - xt.tv_nsec;
tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
tk_set_xtime(tk, ts);
timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
write_seqcount_end(&tk_core.seq);
raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
/* signal hrtimers about time change */
clock_was_set();
return 0;
}
//获得当前系统内核的时间,距离1970的整秒数
unsigned long get_seconds(void)
{
struct timekeeper *tk = &tk_core.timekeeper;
return tk->xtime_sec;
}
//初始化一个timer_list变量,将此定时器插入到内核定时器模块中,并确定由哪个cpu处理
static struct timer_list my_timer;//定义一个软件定时器
init_timer(&my_timer);
//计算输入的年月日时分秒距离1970的秒数
static inline unsigned long mktime(const unsigned int year,
const unsigned int mon,
const unsigned int day,
const unsigned int hour,
const unsigned int min,
const unsigned int sec
)
{
return mktime64(year, mon, day, hour, min, sec);
}
//更改定时器的到期时间,使定时器timer执行新的expires
//返回1 修改成功;返回0 修改失败
int mod_timer(struct timer_list *timer,unsigned long expires);
=//等价于
del_timer(my_timer);
my_timer->expires=expires;
add_timer(timer);
//将一个64位有符号整数 nsec 转成 timespec 结构体时间
struct timespec ns_to_timespec(const s64 nsec)
{
struct timespec ts;
s32 rem;
if (!nsec)
return (struct timespec) {0, 0};
ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
if (unlikely(rem < 0)) {
ts.tv_sec--;
rem += NSEC_PER_SEC;
}
ts.tv_nsec = rem;
return ts;
}
//将一个64位有符号整数 nsec 转成 timeval 结构体时间
struct timeval ns_to_timeval(const s64 nsec)
{
struct timespec ts = ns_to_timespec(nsec);
struct timeval tv;
tv.tv_sec = ts.tv_sec;
tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;
return tv;
}
//将秒 sec 和纳秒 nsec 转换成 timespec 变量表示的时间
void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
{
while (nsec >= NSEC_PER_SEC) {
asm("" : "+rm"(nsec));
nsec -= NSEC_PER_SEC;
++sec;
}
while (nsec < 0) {
asm("" : "+rm"(nsec));
nsec += NSEC_PER_SEC;
--sec;
}
ts->tv_sec = sec;
ts->tv_nsec = nsec;
}
//用于测试动态定时器的状态是否处于活跃态
//0-活跃 1-非活跃
static inline int timer_pending(const struct timer_list *timer)
{
return timer->entry.next != NULL;
}
static struct timer_list my_timer;//定义一个软件定时器
struct timer_list {
struct list_head entry; //定时器链表的入口
unsigned long expires; //定时器超时时的节拍数
void (*function)(unsigned long); //【重要】定时器处理函数
unsigned long data; //传给定时器处理函数的长整型参数
struct tvec_t_base_s *base; //定时器内部值,用户不使用
#ifdef CONFIG_TIMER_STATS
void *start_site;
char start_comm[16];
int start_pid;
#endif
};
void my_timer_function(...);//定义自己的软件定时器函数
init_timer(&my_timer);
my_timer.function=my_timer_function;
add_timer(my_timer);
//获得当前系统内核的时间,该时间是距离1970年1月1日0时0分0秒的时间,用秒和纳秒表示
//timespec里面是秒和纳秒
struct timespec current_kernel_time(void)
{
struct timekeeper *tk = &tk_core.timekeeper;
struct timespec64 now;
unsigned long seq;
do {
seq = read_seqcount_begin(&tk_core.seq);
now = tk_xtime(tk);
} while (read_seqcount_retry(&tk_core.seq, seq));
return timespec64_to_timespec(now);
}
//用于将非活跃状态的定时器从动态定时器链表中删除
//返回1说明删除成功,返回0说明定时器正在执行或已经不存在,删除无效
int del_timer(struct timer_list *timer);
//获取当前系统内核时间,保存再tv结构体中,距离1970.1.1 00:00:00的秒差
void do_gettimeofday(struct timeval *tv)
{
struct timespec64 now;
getnstimeofday64(&now);
tv->tv_sec = now.tv_sec;
tv->tv_usec = now.tv_nsec/1000;
}
//设定系统内核时间,设定为 ts 所代表的时间,距离1970的秒数
int do_settimeofday64(const struct timespec64 *ts)
{
struct timekeeper *tk = &tk_core.timekeeper;
struct timespec64 ts_delta, xt;
unsigned long flags;
if (!timespec64_valid_strict(ts))
return -EINVAL;
raw_spin_lock_irqsave(&timekeeper_lock, flags);
write_seqcount_begin(&tk_core.seq);
timekeeping_forward_now(tk);
xt = tk_xtime(tk);
ts_delta.tv_sec = ts->tv_sec - xt.tv_sec;
ts_delta.tv_nsec = ts->tv_nsec - xt.tv_nsec;
tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
tk_set_xtime(tk, ts);
timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
write_seqcount_end(&tk_core.seq);
raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
/* signal hrtimers about time change */
clock_was_set();
return 0;
}
//获得当前系统内核的时间,距离1970的整秒数
unsigned long get_seconds(void)
{
struct timekeeper *tk = &tk_core.timekeeper;
return tk->xtime_sec;
}
//初始化一个timer_list变量,将此定时器插入到内核定时器模块中,并确定由哪个cpu处理
static struct timer_list my_timer;//定义一个软件定时器
init_timer(&my_timer);
//计算输入的年月日时分秒距离1970的秒数
static inline unsigned long mktime(const unsigned int year,
const unsigned int mon,
const unsigned int day,
const unsigned int hour,
const unsigned int min,
const unsigned int sec
)
{
return mktime64(year, mon, day, hour, min, sec);
}
//更改定时器的到期时间,使定时器timer执行新的expires
//返回1 修改成功;返回0 修改失败
int mod_timer(struct timer_list *timer,unsigned long expires);
=//等价于
del_timer(my_timer);
my_timer->expires=expires;
add_timer(timer);
//将一个64位有符号整数 nsec 转成 timespec 结构体时间
struct timespec ns_to_timespec(const s64 nsec)
{
struct timespec ts;
s32 rem;
if (!nsec)
return (struct timespec) {0, 0};
ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
if (unlikely(rem < 0)) {
ts.tv_sec--;
rem += NSEC_PER_SEC;
}
ts.tv_nsec = rem;
return ts;
}
//将一个64位有符号整数 nsec 转成 timeval 结构体时间
struct timeval ns_to_timeval(const s64 nsec)
{
struct timespec ts = ns_to_timespec(nsec);
struct timeval tv;
tv.tv_sec = ts.tv_sec;
tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;
return tv;
}
//将秒 sec 和纳秒 nsec 转换成 timespec 变量表示的时间
void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
{
while (nsec >= NSEC_PER_SEC) {
asm("" : "+rm"(nsec));
nsec -= NSEC_PER_SEC;
++sec;
}
while (nsec < 0) {
asm("" : "+rm"(nsec));
nsec += NSEC_PER_SEC;
--sec;
}
ts->tv_sec = sec;
ts->tv_nsec = nsec;
}
//用于测试动态定时器的状态是否处于活跃态
//0-活跃 1-非活跃
static inline int timer_pending(const struct timer_list *timer)
{
return timer->entry.next != NULL;
}