增加开机时间校准 3396/1 3396/head 3397/target/1
authorcaisking <caiyqm@qq.com>
Thu, 30 Apr 2026 08:45:09 +0000 (16:45 +0800)
committercaisking <caiyqm@qq.com>
Thu, 30 Apr 2026 08:45:09 +0000 (16:45 +0800)
code/sdk/middleware/chips/brandy/exception/chip_system_time.c
code/sdk/zhihui/utils/custom_utils.c

index ad7e093..b7cd666 100644 (file)
 #define MAX_TIMEZONE_HOURS      24
 #define TIME_MAX                64
 #define TIME_FLOW_PREFIX        "[TIME_FLOW][时间链路] "
+#define MIN_VALID_RESTORE_SEC   946684800UL /* 2000-01-01 00:00:00 */
+#define DEFAULT_FALLBACK_UTC_SEC 1735660800UL /* 2025-01-01 00:00:00 */
+#define TIME_BIN_PATH           "/user/userdata/time.bin"
+
+static uint32_t build_reasonable_fallback_local_sec(uint16_t timezone_quarters)
+{
+    uint32_t utc_now = get_current_timestamp();
+    uint32_t zone_offset_sec = timezone_quarters * MINUTES_PER_QUARTER * SECONDS_PER_MINUTE;
+
+    /*
+     * Prefer current RTC time when it already looks reasonable; otherwise
+     * fallback to a fixed baseline to avoid 1970/zero timestamp.
+     */
+    if (utc_now >= MIN_VALID_RESTORE_SEC) {
+        return utc_now + zone_offset_sec;
+    }
+    return DEFAULT_FALLBACK_UTC_SEC + zone_offset_sec;
+}
+
+static void save_time_bin(uint32_t utc_sec)
+{
+    FILE *fp = fopen(TIME_BIN_PATH, "wb");
+    if (fp == NULL) {
+        printf(TIME_FLOW_PREFIX "save_time_bin: open failed, path=%s\r\n", TIME_BIN_PATH);
+        return;
+    }
+    size_t write_cnt = fwrite(&utc_sec, sizeof(utc_sec), 1, fp);
+    fclose(fp);
+    if (write_cnt != 1) {
+        printf(TIME_FLOW_PREFIX "save_time_bin: write failed\r\n");
+        return;
+    }
+    printf(TIME_FLOW_PREFIX "save_time_bin: utc_sec=%u\r\n", utc_sec);
+}
+
+static bool load_time_bin(uint32_t *utc_sec)
+{
+    if (utc_sec == NULL) {
+        return false;
+    }
+
+    FILE *fp = fopen(TIME_BIN_PATH, "rb");
+    if (fp == NULL) {
+        return false;
+    }
+    size_t read_cnt = fread(utc_sec, sizeof(*utc_sec), 1, fp);
+    fclose(fp);
+    if (read_cnt != 1 || *utc_sec < MIN_VALID_RESTORE_SEC) {
+        return false;
+    }
+    return true;
+}
 
 void print_time(calendar_t *date)
 {
@@ -63,6 +115,7 @@ void save_time(void)
     printf(TIME_FLOW_PREFIX "save_time: local_sec=%u, write_calendar_ms=%llu\r\n",
         (uint32_t)get_local_timestamp(), (unsigned long long)time_sec);
     uapi_calendar_set_timestamp(time_sec);
+    save_time_bin(get_current_timestamp());
 }
 
 uint32_t get_current_timestamp(void)
@@ -105,11 +158,34 @@ void restore_time(void)
     uapi_calendar_get_timestamp(&sec);
     printf("callendar timestamp = %lld \r\n", sec);
     sec = sec / MSEC_PER_SEC;
+    uint16_t timezone_quarters = uapi_get_timezone();
+    if ((sec < MIN_VALID_RESTORE_SEC) || (sec > UINT32_MAX)) {
+        uint32_t file_utc_sec = 0;
+        if (load_time_bin(&file_utc_sec)) {
+            printf(TIME_FLOW_PREFIX "restore_time: invalid calendar timestamp=%llu, use time.bin utc=%u\r\n",
+                (unsigned long long)sec, file_utc_sec);
+            sync_time_utc(file_utc_sec, timezone_quarters);
+        } else {
+            uint32_t fallback_local_sec = build_reasonable_fallback_local_sec(timezone_quarters);
+            printf(TIME_FLOW_PREFIX "restore_time: invalid calendar timestamp=%llu, use fallback_local=%u\r\n",
+                (unsigned long long)sec, fallback_local_sec);
+            sync_time(fallback_local_sec, timezone_quarters);
+        }
+    } else {
     printf(TIME_FLOW_PREFIX "restore_time: read_calendar_sec=%llu, timezone_quarters=%u\r\n",
-        (unsigned long long)sec, uapi_get_timezone());
-    sync_time(sec, uapi_get_timezone());
-    printf(TIME_FLOW_PREFIX "restore_time: after_sync utc_now=%u, local_now=%u\r\n",
-        get_current_timestamp(), get_local_timestamp());
+        (unsigned long long)sec, timezone_quarters);
+        sync_time((uint32_t)sec, timezone_quarters);
+    }
+    uint32_t utc_now = get_current_timestamp();
+    uint32_t local_now = get_local_timestamp();
+    printf(TIME_FLOW_PREFIX "restore_time: after_sync utc_now=%u, local_now=%u\r\n", utc_now, local_now);
+
+    struct tm local_tm = {0};
+    time_t utc_sec = (time_t)utc_now;
+    localtime_r(&utc_sec, &local_tm);
+    printf(TIME_FLOW_PREFIX "restore_time: actual_local_time=%04d-%02d-%02d %02d:%02d:%02d\r\n",
+        local_tm.tm_year + 1900, local_tm.tm_mon + 1, local_tm.tm_mday,
+        local_tm.tm_hour, local_tm.tm_min, local_tm.tm_sec);
 }
 uint32_t sync_time_utc(uint32_t timestamp, uint32_t timezone_quarters)
 {
index 6a7728e..292b25d 100644 (file)
@@ -277,6 +277,7 @@ uint32_t zh_set_sn(uint8_t *buf_sn, uint32_t len_sn)
 
 #include "pm_control.h"
 #include "non_os_reboot.h"
+#include "calendar_porting.h"
 #define PM_SHIPMODE_DELAY_SLEEP_MS   100
 
 void mcu_reset(void)
@@ -293,6 +294,9 @@ static void poweroff_bt_dsp_display(void)
 }
 void mcu_poweroff(void)
 {
+    /* 关机前开启calendar校准,确保自动开机定时持续刷新。 */
+    uapi_calendar_calibration_enable();
+
     /* clr ulp int and event */
     writel(0x5702C1E4, 0x3F);
     writel(0x5702C1EC, 0x3F);
@@ -358,6 +362,7 @@ void uapi_poweroff_device(void)
 void uapi_reboot_device(void)
 {
     PRINT("[PWR_FLOW] uapi_reboot_device: enter\r\n");
+    uapi_calendar_calibration_enable();
     //重启前要保存时间
     uapi_calendar_store_date();
     PRINT("[PWR_FLOW] uapi_reboot_device: calendar stored\r\n");