You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VxWorks系统中如何在usrAppInit.c中设置跨重启持久化的系统时间

VxWorks系统中如何在usrAppInit.c中设置跨重启持久化的系统时间

看起来你已经找对了方向,但可能在硬件RTC的写入环节没做足——要让时间跨重启保存,核心是把时间真正写入硬件实时时钟(RTC)芯片,而不只是修改系统的软件时钟。我来帮你梳理问题并给出修正方案:

你的现有代码存在的几个关键点问题

  1. 没有检查vxbRtcSet的返回值:如果这个调用失败,说明根本没把时间写入硬件RTC,重启后自然会丢失
  2. 直接使用gmtime返回的静态缓冲区:gmtime返回的是全局静态内存,后续其他时间操作可能会覆盖这个数据,导致写入RTC的时间出错
  3. 没有验证RTC写入是否成功:写完后最好读回来确认硬件已经保存了正确时间

修正后的完整实现方案

把下面的代码整合到你的usrAppInit.c中,它会确保时间被写入硬件RTC,且重启后依然有效:

#include <time.h>
#include <vxWorks.h>
#include <vxbRtcLib.h>
#include <ipcom_printf.h>

void setPersistentSystemTime(void)
{
    struct timespec targetTime;
    struct tm rtcTm; // 用本地变量存储时间结构,避免静态缓冲区覆盖问题
    struct tm *tmpTmPtr;

    // 1. 打印当前系统时间(用于对比)
    if (clock_gettime(CLOCK_REALTIME, &targetTime) != OK)
    {
        ipcom_printf("%s[%d] ERROR: 读取当前系统时间失败\n", __FUNCTION__, __LINE__);
        return;
    }
    ipcom_printf("%s[%d] 初始系统时间: %lx.%lx, %s\n", __FUNCTION__, __LINE__,
                 (unsigned long)targetTime.tv_sec, (unsigned long)targetTime.tv_nsec, 
                 ipcom_ctime(&targetTime.tv_sec));

    // 2. 设置你需要的目标时间(这里用你指定的1674065500,对应2023-01-19 12:11:40 GMT)
    targetTime.tv_sec = 1674065500UL;
    targetTime.tv_nsec = 0;

    // 3. 转换为GMT格式的tm结构,并复制到本地变量
    tmpTmPtr = gmtime(&targetTime.tv_sec);
    if (tmpTmPtr == NULL)
    {
        ipcom_printf("%s[%d] ERROR: 时间格式转换失败\n", __FUNCTION__, __LINE__);
        return;
    }
    rtcTm = *tmpTmPtr; // 复制静态缓冲区内容到本地变量,避免后续被覆盖

    // 4. 将时间写入硬件RTC(这是持久化的核心步骤)
    if (vxbRtcSet(&rtcTm) != OK)
    {
        ipcom_printf("%s[%d] ERROR: 写入硬件RTC失败\n", __FUNCTION__, __LINE__);
        return;
    }

    // 5. 验证RTC写入是否成功
    if (vxbRtcGet(&rtcTm) != OK)
    {
        ipcom_printf("%s[%d] ERROR: 读取硬件RTC失败\n", __FUNCTION__, __LINE__);
        return;
    }
    // 把RTC读取到的时间转换回时间戳,同步系统软件时钟
    targetTime.tv_sec = mktime_gmt(&rtcTm); // 使用GMT版本的mktime,避免时区偏移问题
    targetTime.tv_nsec = 0;
    if (clock_settime(CLOCK_REALTIME, &targetTime) != OK)
    {
        ipcom_printf("%s[%d] ERROR: 更新系统软件时钟失败\n", __FUNCTION__, __LINE__);
        return;
    }

    // 6. 再次打印系统时间确认结果
    if (clock_gettime(CLOCK_REALTIME, &targetTime) == OK)
    {
        ipcom_printf("%s[%d] 设置后系统时间: %lx.%lx, %s\n", __FUNCTION__, __LINE__,
                     (unsigned long)targetTime.tv_sec, (unsigned long)targetTime.tv_nsec, 
                     ipcom_ctime(&targetTime.tv_sec));
    }
    else
    {
        ipcom_printf("%s[%d] ERROR: 读取设置后系统时间失败\n", __FUNCTION__, __LINE__);
    }
}

然后在usrAppInit函数的末尾添加调用:

void usrAppInit(void)
{
    // ... 你原有的初始化代码 ...

    // 设置持久化系统时间
    setPersistentSystemTime();
}

关键注意事项

  1. 硬件RTC的后备电池:如果你的硬件RTC没有后备电池,就算写入成功,断电重启后时间依然会丢失——这是硬件层面的问题,需要确认硬件配置
  2. RTC驱动初始化时机:确保usrAppInit执行时,RTC驱动已经完成初始化。如果不确定,可以在代码开头添加vxbDevFind("rtc")检查设备是否存在
  3. 时区问题:一定要使用gmtime和mktime_gmt来处理时间,避免时区转换导致的时间偏差
  4. 避免重复设置:如果不需要每次启动都强制设置时间,可以添加判断逻辑,比如只有当RTC时间远早于目标时间时才执行写入操作

备注:内容来源于stack exchange,提问作者PeterVE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 14:42:34