系统时间¶
Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.
功能概述¶
系统时间表示在计算机系统中的时间与日期。通常用系统时钟(System Clock)从某个时间起点的嘀嗒数(Ticks)。
在大部分系统中,时间是不可或缺的一部分,UniRTOS设备有几个时间,支持多种时间信息及时间同步,如硬件时间时钟(RTC)模块、时间(utime)模块、定时器(Timer)模块及时间同步协议NITZ模块和NTP模块。
UniRTOS设备时间功能应用如下图所示:
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微秒。通常也叫做系统时钟周期,是计算机中最基本的、最小的时间单位。
应用
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位整型。
应用逻辑流程图¶
示例代码¶
完整示例代码请查看https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/system/time/time.c
常见问题¶
模块关机(不断电),RTC是否还在运行?¶
在模块上电后,无论模块状态如何(运行模式、低功耗模式、处于复位状态或者关机状态),只要电源电压保持在工作范围内,RTC不会停止工作,之前的时间就不会丢失。