系统时间

Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.


功能概述

系统时间表示在计算机系统中的时间与日期。通常用系统时钟(System Clock)从某个时间起点的嘀嗒数(Ticks)。

在大部分系统中,时间是不可或缺的一部分,UniRTOS设备有几个时间,支持多种时间信息及时间同步,如硬件时间时钟(RTC)模块、时间(utime)模块、定时器(Timer)模块及时间同步协议NITZ模块和NTP模块。

UniRTOS设备时间功能应用如下图所示:

../../_images/image_A7XKbks1Ao2euHxUheYcoIuCn0e.webp

RTC

实时时钟(Real-Time Clock,简称RTC)是一种集成电路。系统可以通过RTC建立和保持系统时间,帮助用户获得精确的实时时间,为电子系统提供精确的时间基准。

RTC可以提供独立于操作系统的时间计时服务,即使设备关机(不断电)也能保持时间的准确性。

RTC ALARM

闹钟是被设计成会在特定的时间向用户发出讯号的时钟,用来提醒其它事务。

在UniRTOS中,闹钟用于设置RTC到期时间,时间到期就会调用注册的回调函数。该方式也用于低功耗唤醒,在低功耗状态下,通过RTC进行唤醒工作。

// 1. 设置闹钟(60秒后)
qosa_rtc_set_alarm(&tm);
qosa_rtc_enable_alarm(1);

// 2. 进入低功耗睡眠(消耗最少功率)
qosa_task_sleep_sec(100);  // 睡眠时间 > 闹钟时间

// 3. 60秒后RTC闹钟触发 → 回调函数执行 → 设备唤醒

System Tick

系统节拍通常是指CPU时钟,是操作系统的心脏,维持着整个系统运行的稳定性。操作系统要实现时间上的管理,必须依赖于系统节拍。

系统节拍是从开机开始一个不断递增的计数器,其时间精度取决于硬件平台底层的时钟。

原理

系统节拍一般由晶振产生,以精确和固定的时间间隔,触发电信号,通过电信号翻转产生一个Tick,设备处理一次数据。比如晶振12MHZ = 12 × 10的6次方,即每秒发出12000000个脉冲信号,那么发出一个脉冲的时间就是时钟周期,也就是1/12微秒。通常也叫做系统时钟周期,是计算机中最基本的、最小的时间单位。

../../_images/image_LnjIbS96SoOfJix10ZocKtDxnie.webp

应用

System Tick是系统中最小的时间刻度,因此可以基于此项接口实现高精度时间管理。

 QLOGV("===== Measure using System Tick =====");
    
    qosa_uint32_t tick_start = 0;
    qosa_uint32_t tick_end = 0;
    qosa_uint32_t tick_diff = 0;
    
    // Get start tick
    tick_start = qosa_get_system_tick_cnt();
    
    // ---- Code to be measured ----
    volatile int sum = 0;
    for (int i = 0; i < 10000; i++)
    {
        sum += i;
    }
    // --------- End of code ---------
    
    // Get end tick
    tick_end = qosa_get_system_tick_cnt();
    
    // Calculate tick difference
    tick_diff = tick_end - tick_start;
    
    QLOGD("Start tick: %u, End tick: %u", tick_start, tick_end);
    QLOGD("Tick difference: %u", tick_diff);
    
    // Note: To convert tick to milliseconds:
    // tick_ms = tick_diff * (1000 / CONFIG_QOSA_SYS_TICK_PER_SECOND)
    // Typical CONFIG_QOSA_SYS_TICK_PER_SECOND = 1000, so 1 tick = 1ms
  

系统定时器

相关接口详情,请参考 定时器应用指导

时间差

    QLOGV("===== Measure in Seconds =====");
    
    qosa_time_t time_start = 0;
    qosa_time_t time_end = 0;
    qosa_time_t time_diff = 0;
    
    // Get start time (seconds since 1970-01-01)
    time_start = qosa_get_system_time_seconds();
    
    // ---- Code to be measured ----
    // For example, sleep for 2 seconds
    qosa_task_sleep_sec(2);
    // --------- End of code ---------
    
    // Get end time
    time_end = qosa_get_system_time_seconds();
    
    // Calculate time difference
    time_diff = time_end - time_start;
    
    QLOGD("Start: %lld s, End: %lld s", time_start, time_end);
    QLOGD("Code execution time: %lld s (seconds)", time_diff);
    QLOGV("===== Measure in Milliseconds =====");
    
    qosa_time_t time_start = 0;
    qosa_time_t time_end = 0;
    qosa_time_t time_diff = 0;
    
    // Get start time (milliseconds since 1970-01-01)
    time_start = qosa_get_system_time_milliseconds();
    
    // ---- Code to be measured ----
    // For example, sleep for 100ms
    qosa_task_sleep_ms(100);
    // --------- End of code ---------
    
    // Get end time
    time_end = qosa_get_system_time_milliseconds();
    
    // Calculate time difference
    time_diff = time_end - time_start;
    
    QLOGD("Start: %lld ms, End: %lld ms", time_start, time_end);
    QLOGD("Code execution time: %lld ms (milliseconds)", time_diff);
void example_measure_microseconds(void)
{
    QLOGV("===== Measure in Microseconds =====");
    
    qosa_time_t time_start = 0;
    qosa_time_t time_end = 0;
    qosa_time_t time_diff = 0;
    
    // Get start time (microseconds since 1970-01-01)
    time_start = qosa_get_system_time_microseconds();
    
    // ---- Code to be measured ----
    // For example, a simple loop
    volatile int sum = 0;
    for (int i = 0; i < 1000; i++)
    {
        sum += i;
    }
    // --------- End of code ---------
    
    // Get end time
    time_end = qosa_get_system_time_microseconds();
    
    // Calculate time difference
    time_diff = time_end - time_start;
    
    QLOGD("Start: %lld us, End: %lld us", time_start, time_end);
    QLOGD("Code execution time: %lld us (microseconds)", time_diff);
}

UTC时间

UTC时间(Universal Time Coordinated, 世界标准时间或世界协调时间),以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。

全球统一时间,但是由于地球旋转导致不同地域的人看到的日出日落的时间不同,全球同一时间显然不符合各地的作息,因此根据地球的地理位置,人为将地球划分成24个不同的时区。因此在UTC的基础上各地区形成本地时间。

本地时间 = UTC时间 + 时区差,比如北京时区是东八区,领先UTC 8个小时,此时如果想获取北京时间,需要将时区配置到东区即可。

UniRTOS提供了本地时间接口以及时区配置接口,系统默认配置在东八区,如果您处在不同的时区,可以根据自己的需求,配置到您所处位置的时区。

// 对应: utime.setTimeZone(8)
qosa_rtc_set_timezone(32);  // 32 = 8 * 4(四分之一小时单位)

// 对应: utime.localtime()  
qosa_rtc_get_localtime(&local_time);
qosa_rtc_gmtime_r(&local_time, &tm);
// 打印: 2026-06-17 23:30:45 (UTC+8)

时间同步

所谓时间同步,即要求各点之间的绝对时间相同。在我们生活中可能会遇到,钟表长时间运行后,需要手动对表,防止时间偏差太大。那么长时间设备运行为什么时间会有偏差?在连网设备上是如何进行对时操作呢?在一些场景对各设备间时间一致性要求较高如何处理?

带有时间的设备,都是靠本地时钟源进行控制时间走时,长时间运行时,会受到本身精度或者环境的影响,出现偏差,此时对于时间要求较高的场景下,就需要对设备时间进行同步,保证运行的稳定性,常用的方式通过NTP向标准时间服务器进行时间同步(如全球NTP授时服务器pool.ntp.org),或者向自己设计的时间服务器进行时间同步。

系统时间API

头文件

qosa_rtc.h

函数概览

函数

描述

qosa_get_system_tick_cnt

获取系统内部运行的时钟节拍数(非时间)

qosa_get_system_time

获取当前系统时间

qosa_get_system_time_seconds

获取自1970年1月1日以来的秒数

qosa_get_system_time_milliseconds

获取自1970年1月1日以来的毫秒数

qosa_get_system_time_microseconds

获取自1970年1月1日以来的微秒数

函数详解

qosa_get_system_tick_cnt

  • 功能描述
    获取系统内部运行的时钟节拍数(非时间)。

  • 函数原型

qosa_uint32_t qosa_get_system_tick_cnt(void)
  • 参数说明

  • 返回值说明
    返回系统内部运行的时钟节拍数

qosa_get_system_time

  • 功能描述
    获取当前系统时间,并存储到 qosa_time_info_t 结构体中。

  • 函数原型

qosa_bool_t qosa_get_system_time(qosa_time_info_t *time)
  • 参数说明

参数名

输入/输出

类型

说明

time

输出

qosa_time_info_t*

指向 qosa_time_info_t 结构体的指针,用于存储当前系统时间;详见 qosa_time_info_t

  • 返回值说明
    QOSA_TRUE:函数执行成功
    QOSA_FALSE:函数执行失败

qosa_get_system_time_seconds

  • 功能描述
    获取自1970年1月1日以来的秒数。

  • 函数原型

qosa_time_t qosa_get_system_time_seconds(void)
  • 参数说明

  • 返回值说明
    返回自1970年1月1日以来的秒数,qosa_time_t 是通过 typedef 关键字定义的类型别名,实际对应 qosa_uint64_t 无符号64位整型。

qosa_get_system_time_milliseconds

  • 功能描述
    获取自1970年1月1日以来的毫秒数。

  • 函数原型

qosa_time_t qosa_get_system_time_milliseconds(void)
  • 参数说明

  • 返回值说明
    返回自1970年1月1日以来的毫秒数,qosa_time_t 是通过 typedef 关键字定义的类型别名,实际对应 qosa_uint64_t 无符号64位整型。

qosa_get_system_time_microseconds

  • 功能描述
    获取自1970年1月1日以来的微秒数。

  • 函数原型

qosa_time_t qosa_get_system_time_microseconds(void)
  • 参数说明

  • 返回值说明
    返回自1970年1月1日以来的微秒数,qosa_time_t 是通过 typedef 关键字定义的类型别名,实际对应 qosa_uint64_t 无符号64位整型。

应用逻辑流程图

../../_images/image_ABzcb9R1voEcU7xxFMgcRPj6nde.webp

示例代码

完整示例代码请查看https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/system/time/time.c

常见问题

模块关机(不断电),RTC是否还在运行?

在模块上电后,无论模块状态如何(运行模式、低功耗模式、处于复位状态或者关机状态),只要电源电压保持在工作范围内,RTC不会停止工作,之前的时间就不会丢失。