systime开发指南
概述
系统时间模块通过LiteOS接口操作系统时间,支持获取和设置系统时间。
时间系统架构

快速跑通 Systime Demo
功能说明
系统时间示例 在 20 ms 等待前后读取系统时间并校验时间向前推进。该测试只读时间,不修改系统时钟,也不依赖外接硬件。
Demo 代码归档路径
samples/native_samples/systime/
├── CMakeLists.txt # 独立组件构建配置
├── README.md # 项目级运行说明
├── systime_demo.c # 系统时间读取、增量计算和 AT 指令
└── systime_demo.h # 对外运行接口和 AT 注册函数声明
编译与烧录
完成一站式 CLI 环境配置后执行:
使用一站式 CLI 烧写固件并打开 UART2 串口监视器。以下为 Windows USB DFU 示例;将 COM3 替换为实际日志串口,其他参数参见一站式 CLI 开发环境使用指南。
fbb flash -f "$env:FBB_SDK_DIR\output\3322\fwpkg\diting-community.fwpkg" --chip 3322 -d --timeout 180
fbb monitor --port COM3 --baud 750000
使用方式
预期结果
实际增量可能受任务调度影响而略大于 20000 us:
需要一次性检查 Systick、Systime、TCXO 等板载能力时,也可以执行 AT+DRIVERSELFTEST。
文件结构与代码走读
文件职责
| 文件 | 职责 | 关键内容 |
|---|---|---|
systime_demo.c |
获取前后系统时间、计算微秒差值并判断结果 | diting_systime_demo_run() |
systime_demo.h |
公开运行和 AT 注册接口 | at_diting_systime_example_cmd_register() |
CMakeLists.txt |
定义独立组件和注册宏 | diting_systime_sample、AT_DITING_EXAMPLE_SYSTIME_TEST |
README.md |
说明只读验证边界和预期结果 | AT+SYSTIMETEST |
核心流程
struct timeval before = {0};
struct timeval after = {0};
if (gettimeofday(&before, NULL) != 0) {
return false;
}
(void)osal_msleep(SYSTIME_DEMO_DELAY_MS);
if (gettimeofday(&after, NULL) != 0) {
return false;
}
int64_t delta_us = ((int64_t)after.tv_sec - (int64_t)before.tv_sec) * 1000000LL +
((int64_t)after.tv_usec - (int64_t)before.tv_usec);
秒差和微秒差统一换算为有符号 64 位微秒数,避免跨秒时只减 tv_usec 得到负值。示例仅检查时间是否正常推进;设置日期、时区和时间同步不属于该无损冒烟测试。
基于 Systime Demo 开发自己的应用
- 复制 samples/native_samples/systime,修改组件名和构建开关,保留
diting_systime_demo_run()这类可直接调用的运行函数。 - 从应用任务、系统服务或
app_run启动入口调用运行函数。 - 需要显示日期时,在取得系统时间后再进行时区和日历转换,不要直接修改底层计时基准。
- 计算时间差时同时处理秒和微秒,并使用 64 位有符号类型。
- 设置系统时间的用例应单独提供业务函数和输入参数,避免基础自测改变设备时间。
- 在上层 CMake 和目标配置中增加新组件入口。
如果需要串口回归,可为只读和设置操作分别增加受控 AT 入口;AT 命令不是系统时间业务接口的前置条件。
功能描述
系统时间模块提供的接口:
| 接口声明 | 功能说明 |
|---|---|
| gettimeofday64() | 获取当前时间 |
| settimeofday64() | 设置系统时间 |
开发指引
获取当前时间
struct timeval64 nowTime = {0};
if (gettimeofday64(&nowTime, NULL)) {
PRINTK("gettime failed...\n");
return DATE_ERR;
}
PRINTK("Current time: %lld.%06lld\n", nowTime.tv_sec, nowTime.tv_usec);
输出示例:
设置当前时间
struct timeval64 tv = {0};
struct timezone tz;
tv.tv_sec = 1700000000; // Unix时间戳
tv.tv_usec = 0; // 微秒
tz.tz_minuteswest = 0; // 西区区时
tz.tz_dsttime = 0; // 夏令时
if (settimeofday64(&tv, &tz)) {
PRINTK("settime failed...\n");
return DATE_ERR;
}
PRINTK("Time set successfully\n");
Unix时间戳转换
// 时间戳转日期时间
struct timeval64 timestamp;
timestamp.tv_sec = 1700000000; // 2023-11-14 22:13:20 UTC
struct timeval64 nowTime = {0};
if (gettimeofday64(&nowTime, NULL) == 0) {
PRINTK("Current Unix timestamp: %lld\n", nowTime.tv_sec);
}
时区设置
struct timeval64 tv = {0};
struct timezone tz;
// 设置为北京时间(UTC+8)
tz.tz_minuteswest = -480; // 西区8小时 = -480分钟
tz.tz_dsttime = 0; // 不使用夏令时
tv.tv_sec = 1700000000;
tv.tv_usec = 0;
settimeofday64(&tv, &tz);
注意事项
-
时间戳单位:Unix时间戳,单位为秒(从1970-01-01 00:00:00 UTC起算)
-
时区设置:
tz.tz_minuteswest表示当前时区相对于UTC的偏移量(西区为正,东区为负) -
夏令时:
tz.tz_dsttime用于夏令时补偿,通常设为0 -
时间一致性:修改系统时间可能影响基于时间戳的功能(如日志时间、文件时间戳等)

常见时区对应值:
| 时区 | tz_minuteswest |
|---|---|
| UTC | 0 |
| 北京时间(UTC+8) | -480 |
| 东京时间(UTC+9) | -540 |
| 纽约时间(UTC-5) | 300 |
| 洛杉矶时间(UTC-8) | 480 |