eCos timer封装成linux kernel风格

来源:互联网 发布:闹钟软件哪个好 编辑:程序博客网 时间:2024/06/03 19:38
net_gmt_t cloud_gmt;
static alarm_t alarm_list[NR_ALARM];
static os_timer_t timer_list[NR_TIMER];

static int _del_timer(int base_no, int nr_timer, os_timer_t *timer)
{
    int i; // 0-based index

    if (NULL == timer) {
        goto err;
    }

    for (i = base_no; i < nr_timer; i++) {
        if (&timer_list[i] == timer) {
            untimeout(timer->callback, (void *)timer->arg);
            timer_list[i].in_use = false;
            timer = NULL;
            return i;
        }
    }
err:
    return -1;
}

static int _mod_timer(int base_no, int nr_timer, os_timer_t *timer, unsigned long expires)
{
    if (NULL == timer) {
        goto err;
    }

    timer->expires = expires/10;
    timeout(timer->callback, (void *)timer->arg, expires/10);
    return timer->id;
err:
    return -1;
}

static int _setup_timer(int base_no, int nr_timer, os_timer_t *timer, timer_fn fn,
        unsigned long arg, unsigned long expires)
{
    int avail = 0;
    int i; // 0-based index

    if (NULL != timer) {
        for (i = base_no; i < nr_timer; i++) {
            if (&timer_list[i] == timer) {
                timer_list[i].in_use = true;
                avail = 1;
                goto done;
            }
        }
        if (0 == avail || i >= nr_timer) {
            goto err;
        }
    }

    for (i = base_no; i < nr_timer; i++) {
        if (false == timer_list[i].in_use) {
            timer_list[i].in_use = true;
            timer = &timer_list[i];
            avail = 1;
            break;
        }
    }

done:
    if ((i < nr_timer) && (1 == avail)) {
        timer->arg = arg;
        timer->callback = fn;
        timer->expires = expires/10;
        timer->id = i;
        // expires: unit: 10 ms, so 100 means 1 seconds
        timeout(fn, (void *)arg, expires/10);
        return i;
    }
err:
    return -1;
}

API int del_timer(os_timer_t *timer)
{
    return _del_timer(TIMER_BASE_NO, NR_USER_TIMER, timer);
}

API int mod_timer(os_timer_t *timer, unsigned long expires)
{
    return _mod_timer(TIMER_BASE_NO, NR_USER_TIMER, timer, expires);
}

API int setup_timer(os_timer_t *timer, timer_fn fn, unsigned long arg, unsigned long expires)
{
    return _setup_timer(TIMER_BASE_NO, NR_USER_TIMER, timer, fn, arg, expires);
}

/////////////////////////////////////////////////////////////////////
static os_timer_t *alarm_to_timer(alarm_t *alarm)
{
    if (NULL == alarm) {
        return NULL;
    }
    if (false == alarm->in_use) {
        return NULL;
    }

    return &timer_list[alarm->id];
}

API int alarm_init(void)
{
    int timer_id, type;
    //struct timespec time;
    os_timer_t * timer;
    u32 i = 0;
    u32 nv_size = sizeof(alarm_t) * NR_ALARM;
    unsigned long expires;

    //clock_gettime(CLOCK_REALTIME, &time);  //获取相对于1970到现在的秒数
    oem_printf("[OEM] sizeof(time_t): %d, elapsed_secs: %d secs\n",
            sizeof(time_t), time(NULL));

    if (nv_read(NV_ALARM_ARRAY, (char *)&alarm_list[0], nv_size) < 0) {
        goto err;
    }

    for (i = 0; i < NR_ALARM; i++) {
        if (true == alarm_list[i].in_use) {
            oem_printf("[OEM] abs_time_seconds: %d, switch_state: 0x%08x\n",
                    alarm_list[i].abs_time_seconds, alarm_list[i].u.d32);

            if (cloud_gmt.gmt_base_seconds < alarm_list[i].abs_time_seconds) {
                expires = alarm_list[i].abs_time_seconds - cloud_gmt.gmt_base_seconds;
                expires *= 1000;
                type = alarm_list[i].type;
                timer = alarm_to_timer(&alarm_list[i]);

                timer_id = _setup_timer(ALARM_BASE_NO, NR_TIMER, timer, alarm_fn_array[type],
                        alarm_list[i].u.d32, expires);
                if (timer_id >= 0) {
                    oem_printf("[OEM] restart alarm after system boot completed\n");
                } else {
                    oem_printf("[OEM] cannot restart alarm after system boot completed\n");
                }
            } else {
                alarm_list[i].in_use = false;
            }
        }
    }

    return 0;
err:
    return -1;
}

API int alarm_set(alarm_t *alarm, alarm_fn fn, unsigned long arg, unsigned long expires,
        alarm_type_enum_t type)
{
    int alarm_id, timer_id;
    //struct timespec time;
    os_timer_t *timer;
    time_t delta;
    u32 nv_size = sizeof(alarm_t) * NR_ALARM;

    if (type < 0 || type > ALARM_TYPE_ENUM_MAX) {
        oem_printf("[OEM] invalid alarm type: %d\n", type);
        return -1;
    }

    timer_id = _setup_timer(ALARM_BASE_NO, NR_TIMER, timer, fn, arg, expires);
    alarm_id = timer_id - ALARM_BASE_NO;
    if (alarm_id >= 0) {
        alarm = &alarm_list[alarm_id];

        alarm_list[alarm_id].in_use = true;
        alarm_list[alarm_id].id = timer_id;
        alarm_list[alarm_id].type = type;
        
        //clock_gettime(CLOCK_REALTIME, &time);  //获取相对于1970到现在的秒数
        delta = time(NULL) - cloud_gmt.local_elapsed_seconds;
        alarm_list[alarm_id].abs_time_seconds = cloud_gmt.gmt_base_seconds + delta + expires/1000;
        if (ALARM_TYPE_SWITCH == type) {
            alarm_list[alarm_id].u.switch_state = arg;
        }
        // TODO
        // [...]
        if (nv_write(NV_ALARM_ARRAY, &alarm_list[0], nv_size) < 0) {
            oem_printf("[OEM][%s] failed to write NV_ALARM_ARRAY\n", __func__);
        }
        if (nv_commit() < 0) {
            oem_printf("[OEM][%s] failed to commit NV_ALARM_ARRAY\n", __func__);
        }
        return alarm_id;
    }

    return -1;
}

API int alarm_set_repeat(alarm_t *alarm, alarm_fn fn, unsigned long arg, unsigned long expires,
        int type)
{
    int id;

    return -1;
}

API int alarm_cancel(alarm_t *alarm)
{
    int alarm_id, timer_id;
    os_timer_t *timer;
    u32 nv_size = sizeof(alarm_t) * NR_ALARM;

    if (NULL == alarm) {
        goto err;
    }

    timer = alarm_to_timer(alarm);
    timer_id = _del_timer(ALARM_BASE_NO, NR_TIMER, timer);
    alarm_id = timer_id - ALARM_BASE_NO;
    if (alarm_id >= 0) {
        alarm_list[alarm_id].in_use = false;
        if (nv_write(NV_ALARM_ARRAY, &alarm_list[0], nv_size) < 0) {
            oem_printf("[OEM][%s] failed to write NV_ALARM_ARRAY\n", __func__);
        }
        if (nv_commit() < 0) {
            oem_printf("[OEM][%s] failed to commit NV_ALARM_ARRAY\n", __func__);
        }
        alarm = NULL;
        return alarm_id;
    }
err:
    return -1;
}

API alarm_t *id_to_alarm(u32 id)
{
    if (id < 0 || id >= NR_ALARM) {
        return NULL;
    }

    return &alarm_list[id];
}

// time_t gmt_translate2localtime(time_t gmt_time)
// struct tm *gmtime(const time_t *timep)
/* 将时间结构体struct tm的值转化为经过的秒数 */
// time_t mktime(struct tm *tm)
/* translate " DD-mth-YY HH:MM:SS GMT" to elapsed seconds */
// time_t tdate_parse( char* str)
API void get_now_time(void)
{
    struct timespec time;
    struct tm nowtime;

    clock_gettime(CLOCK_REALTIME, &time);  //获取相对于1970到现在的秒数
    localtime_r(&time.tv_sec, &nowtime);
    diag_printf("%04d%02d%02d%02d:%02d:%02d\n", nowtime.tm_year + 1900,
            nowtime.tm_mon + 1, nowtime.tm_mday,
            nowtime.tm_hour, nowtime.tm_min, nowtime.tm_sec);
}
原创粉丝点击