优化GPS的关闭
authorCaisking <Casiking@zhihuishixun.com>
Mon, 23 Mar 2026 10:23:15 +0000 (18:23 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Mon, 23 Mar 2026 10:23:15 +0000 (18:23 +0800)
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/src/TraingModel.cpp
code/sdk/application/wearable/fd272/nativeapp/nativeui/traing/src/TraingNomalView.cpp
code/sdk/zhihui/services/gnss/src/uart_gnss.c

index ec6057b..6b0e5e8 100644 (file)
@@ -3192,9 +3192,51 @@ bool TraingModel::LoadGPSData(const std::string &filePath) {
    }
    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "=== GPS连接状态设置完成 ===");
  }
- //运动心率、gps开启准备
+// 延迟关闭 GNSS:10 秒内若训练重新开启,则取消关闭
+#if defined(SUPPORT_GNSS)
+static osTimerId_t g_delayed_gnss_stop_timer = nullptr;
+static uint32_t g_gnss_stop_request_token = 0;
+static uint32_t g_gnss_stop_execute_token = 0;
+
+static void gnss_delayed_stop_timer_callback(void *arg) {
+  unused(arg);
+  TraingModel *model = TraingModel::GetInstance();
+  if (model == nullptr) {
+    return;
+  }
+  // token 不一致 or 训练已重新开启,则取消本次关闭
+  if (g_gnss_stop_execute_token != g_gnss_stop_request_token ||
+      uapi_dev_runtime_get_train_status() == 1) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "取消本次GPS延迟关闭: execute_token=%u request_token=%u train_status=%d",
+                  g_gnss_stop_execute_token, g_gnss_stop_request_token,
+                  uapi_dev_runtime_get_train_status());
+    return;
+  }
+  GraphicService::GetInstance()->PostGraphicEvent([]() {
+    TraingModel *m = TraingModel::GetInstance();
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "10s后异步执行gnss_stop()");
+    gnss_stop();
+    if (m != nullptr) {
+      m->SetGpsOpen(false);
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gnss_stop()调用完成");
+  });
+}
+#endif
+
+//运动心率、gps开启准备
  void TraingModel::start_training_heart() {
      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始启动GPS定位服务...");
+#if defined(SUPPORT_GNSS)
+    // 训练重新开启时,取消任何待执行的延迟关闭请求
+    g_gnss_stop_request_token++;
+    if (g_delayed_gnss_stop_timer != nullptr) {
+      osTimerStop(g_delayed_gnss_stop_timer);
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "取消待执行的GPS延迟关闭请求, token=%u",
+                  g_gnss_stop_request_token);
+#endif
      //开启心率检测
  #ifdef SUPPORT_PPG_SERVICE
      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "启动心率检测服务");
@@ -3207,16 +3249,33 @@ bool TraingModel::LoadGPSData(const std::string &filePath) {
  void TraingModel::stop_heart_gps() {
    if (gpsopen == true) {
      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开始关闭GPS定位服务...");
-    // 关闭gps
 #if defined(SUPPORT_GNSS)
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "调用gnss_stop()关闭GPS服务");
-    GraphicService::GetInstance()->PostGraphicEvent([]() {
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "异步执行gnss_stop()");
-      gnss_stop();
-      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gnss_stop()调用完成");
-    });
-    gpsopen = false;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS定位服务关闭完成,gpsopen设置为false");
+    // 延迟 10 秒再真正执行 gnss_stop;若期间重新打开训练,则取消这次关闭。
+    g_gnss_stop_request_token++;
+    g_gnss_stop_execute_token = g_gnss_stop_request_token;
+
+    if (g_delayed_gnss_stop_timer == nullptr) {
+      g_delayed_gnss_stop_timer =
+          osTimerNew((osTimerFunc_t)gnss_delayed_stop_timer_callback,
+                     osTimerOnce, nullptr, nullptr);
+    }
+
+    if (g_delayed_gnss_stop_timer != nullptr) {
+      osTimerStop(g_delayed_gnss_stop_timer);
+      osStatus_t ret = osTimerStart(g_delayed_gnss_stop_timer, osMs2Tick(10 * 1000));
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "已发起GPS延迟关闭(10s), token=%u, ret=%ld",
+                    g_gnss_stop_request_token, (long)ret);
+    } else {
+      // 定时器创建失败时兜底:立即关闭,避免资源悬挂
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GPS延迟关闭定时器创建失败,立即执行gnss_stop()");
+      GraphicService::GetInstance()->PostGraphicEvent([]() {
+        gnss_stop();
+      });
+    }
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "GPS延迟关闭已安排,等待10s确认后再真正关闭");
 #endif
     }
      //关闭心率检测
index 40f1497..de72c98 100644 (file)
@@ -79,6 +79,7 @@ namespace OHOS
             return;
         }
 #if defined(SUPPORT_GNSS)
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "初始化心率与GPS");
         InitUILabel(heartrate_label_, -32, 230, 200, 60, "heartrate_label_", "--", DEFAULT_VECTOR_FONT_FILENAME, 30);
         group->Add(heartrate_label_);
         InitUILabel(gps_label_, 295, 230, 200, 60, "label_time", "GPS", DEFAULT_VECTOR_FONT_FILENAME, 30);
index e1da2fc..129d364 100644 (file)
@@ -147,12 +147,14 @@ static void uart_event_task(void const *arg)
                 uint8_t *buf=NULL;
                 uint16_t len=0;
                 // if (gnss_get_current_cmd(last_cfg_cmd_index,&buf,&len)==0)
-                {
+                if (buf != NULL && len > 0) {
                     WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"write next cmd[%d] size=%d! %s \r\n",last_cfg_cmd_index,len);
                     wlen=gnss_write_cmd(buf,len);
+                    WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"write next cmd[%d] done, len=%d, written=%d \r\n",
+                                  last_cfg_cmd_index, len, wlen);
                 }
                 // else
-                {
+                else {
                     WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"no next cmd, stopped! \r\n");
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表结束写入
                 }
@@ -164,6 +166,7 @@ static void uart_event_task(void const *arg)
             uint32_t wlen=0;
             uint8_t *buf=NULL;
             uint16_t len=0;
+            bool handled_no_uart_write = false;
             switch(mail.cmd_type)
             {
                 case GNSS_CMD_CFG_INIT:
@@ -176,31 +179,38 @@ static void uart_event_task(void const *arg)
                             last_cfg_cmd_index = 0;
                         }
                     } 
+                    handled_no_uart_write = true;
                 break;
                 case GNSS_CMD_NMEA_CFG:
                     // gnss_get_nmea_cfg_cmd(&buf,&len);
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表cfg结束写入,开始检测其他指令
+                    handled_no_uart_write = true;
                 break;
                 case GNSS_CMD_START:
                     // gnss_get_start_cmd(&buf,&len);
                     // GnssServerStart();
                     PGnssServerStart();
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表cfg结束写入,开始检测其他指令
+                    handled_no_uart_write = true;
                 break;
                 case GNSS_CMD_STOP:
                     // gnss_get_stop_cmd(&buf,&len);
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表cfg结束写入,开始检测其他指令
+                    handled_no_uart_write = true;
                 break;
                 default:
                     buf = mail.buffer;
                     len = mail.size;
                     break;
             }
-            if (buf!=NULL)
+            if (buf != NULL && len > 0)
             {
-                // wlen=gnss_write_cmd(buf,len);
+                wlen=gnss_write_cmd(buf,len);
                 WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"GNSS_CMD_WRITEDATA cmdtype %d, written len %d\r\n",mail.cmd_type,wlen);
-            }else{
+            } else if (handled_no_uart_write) {
+                WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,
+                              "GNSS_CMD_WRITEDATA cmdtype %d handled (no direct uart write)\r\n", mail.cmd_type);
+            } else {
                 WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"GNSS_CMD_WRITEDATA cmdtype %d failed \r\n",mail.cmd_type);
             }
         }