跳转至

systime开发指南

概述

系统时间模块通过LiteOS接口操作系统时间,支持获取和设置系统时间。

时间系统架构

**时间系统架构**

快速跑通 Systime Demo

功能说明

系统时间示例 在 20 ms 等待前后读取系统时间并校验时间向前推进。该测试只读时间,不修改系统时钟,也不依赖外接硬件。

Demo 代码归档路径

samples/native_samples/systime/
├── CMakeLists.txt       # 独立组件构建配置
├── README.md            # 项目级运行说明
├── systime_demo.c       # 系统时间读取、增量计算和 AT 指令
└── systime_demo.h       # 对外运行接口和 AT 注册函数声明

编译与烧录

完成一站式 CLI 环境配置后执行:

fbb set-target pack_diting_community
fbb build

使用一站式 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

使用方式

AT+SYSTIMETEST

预期结果

实际增量可能受任务调度影响而略大于 20000 us:

[DRV][SYSTIME] delta=20000us
[DRV][SYSTIME] PASS
OK

需要一次性检查 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_sampleAT_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 开发自己的应用

  1. 复制 samples/native_samples/systime,修改组件名和构建开关,保留 diting_systime_demo_run() 这类可直接调用的运行函数。
  2. 从应用任务、系统服务或 app_run 启动入口调用运行函数。
  3. 需要显示日期时,在取得系统时间后再进行时区和日历转换,不要直接修改底层计时基准。
  4. 计算时间差时同时处理秒和微秒,并使用 64 位有符号类型。
  5. 设置系统时间的用例应单独提供业务函数和输入参数,避免基础自测改变设备时间。
  6. 在上层 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);

输出示例:

Current time: 1700000000.000000

设置当前时间

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);

注意事项

  1. 时间戳单位:Unix时间戳,单位为秒(从1970-01-01 00:00:00 UTC起算)

  2. 时区设置tz.tz_minuteswest表示当前时区相对于UTC的偏移量(西区为正,东区为负)

  3. 夏令时tz.tz_dsttime用于夏令时补偿,通常设为0

  4. 时间一致性:修改系统时间可能影响基于时间戳的功能(如日志时间、文件时间戳等)

**时间一致性**:修改系统时间可能影响基于时间戳的功能(如日志时间、文件时间戳等)

常见时区对应值:

时区 tz_minuteswest
UTC 0
北京时间(UTC+8) -480
东京时间(UTC+9) -540
纽约时间(UTC-5) 300
洛杉矶时间(UTC-8) 480