时钟管理

在操作系统中,时间的最小单位是时钟节拍(clock ticks),基于这个,我们可以使用定时器来做一些想做的事情,除此之外,也可以用来计算墙上时间,也就是计算现在的时间,几时几分几秒。读完本章,我们将了解时钟节拍如何产生,并学会使用xbook2的定时器。

时钟节拍

时钟节拍就是,可以对某个时钟硬件进行编程,控制它1s产生多少次时钟中断,我们可以用一个变量sys_ticks来记录这个次数,可以是10次,也可以是100次,甚至是1000次。那么这个就是时钟节拍。xbook2中通过HZ这个变量来表明1s可以产生的时钟节拍数量。

时钟节拍的实现方式

当时钟中断产生时,我们将sys_ticks+=1,我们的定时器和墙上时间就是基于sys_ticks来的。

static int clock_handler(irqno_t irq, void *data)
{
    systicks++;
    timer_ticks++;
    softirq_active(TIMER_SOFTIRQ);
    softirq_active(SCHED_SOFTIRQ);
    return 0;
}

获取时钟节拍

可以通过sys_get_ticks来获取当前的ticks值。

clock_t sys_get_ticks()
{
    return systicks;
}

定时器管理

定时器就是你可以设置一个时间点,当到达这个时间点时,将会产生超时,你可以在超时点做一些你想做的事情。

struct timer_struct;
// callback(timer, arg)
typedef void (*timer_callback_t) (struct timer_struct *, void *); 
/* 定时器 */
typedef struct timer_struct {
    list_t list;                /* 定时器链表 */
    clock_t timeout;            /* 超时点,以ticks为单位 */
    void *arg;                  /* 参数 */
    unsigned long id;           /* 定时器的id值 */
    timer_callback_t callback;  /* 回调函数 */
} timer_t;

定时器有一个回调函数,就是超时时会去调用的函数,来执行使用者需要执行的内容。

墙上时间管理

墙上时间在xbook2中就是计算年月日,时分秒的时间。

typedef struct {
    int second;         /* [0-59] */
    int minute;         /* [0-59] */
    int hour;           /* [0-23] */
    int day;            /* [1-31] */
    int month;          /* [1-12] */
    int year;           /* year */
    int week_day;       /* [0-6] */
    int year_day;       /* [0-366] */
} walltime_t;

最开始这些时间值是从硬件获取,获取后,我们便可以通过时钟节拍sys_ticks来判断是否更新这些时间值。

void walltime_init()
{
    /* 初始化系统时间 */
    //用一个循环让秒相等
    do{
        walltime.year      = time_get_year();
        walltime.month     = time_get_month();
        walltime.day       = time_get_day();
        walltime.hour      = time_get_hour();
        walltime.minute    =  time_get_minute();
        walltime.second    = time_get_second();

        /* 转换成本地时间 */
        /* 自动转换时区 */
#ifdef CONFIG_TIMEZONE_AUTO
        if(walltime.hour >= 16){
            walltime.hour -= 16;
        }else{
            walltime.hour += 8;
        }
#endif /* CONFIG_TIMEZONE_AUTO */
    }while(walltime.second != time_get_second());

    walltime.week_day = walltime_get_week_day(walltime.year, walltime.month, walltime.day);
    walltime.year_day = walltime_get_year_days();

    walltime_printf();
}
static void timer_softirq_handler(softirq_action_t *action)
{
    if (systicks % HZ == 0) {  /* 1s更新一次 */
        walltime_update_second();
    }
    timer_update_ticks();
    alarm_update_ticks();
}

用户程序可以通过系统调用来获取这个时间值,从而得知当前的日期和时间。

int sys_get_walltime(walltime_t *wt)
{
    walltime_t tmp = walltime;
    --tmp.month;
    return mem_copy_to_user(wt, &tmp, sizeof(walltime_t));
}
Copyright © BookOS-developers 2021 all right reserved,powered by Gitbook修订时间: 2021-06-16

results matching ""

    No results matching ""