GPS合并优化 3343/1 3343/head 3344/target/1
authorluozheng <1732036298@qq.com>
Wed, 15 Apr 2026 09:21:53 +0000 (17:21 +0800)
committerluozheng <1732036298@qq.com>
Wed, 15 Apr 2026 09:21:53 +0000 (17:21 +0800)
code/sdk/zhihui/services/gnss/inc/uart_gnss.h
code/sdk/zhihui/services/gnss/sample/pgnss_sample/pgnss_sample.c
code/sdk/zhihui/services/gnss/src/NMEA0183.c
code/sdk/zhihui/services/gnss/src/decodenmea.c
code/sdk/zhihui/services/gnss/src/gnss_ctl.c
code/sdk/zhihui/services/gnss/src/uart_gnss.c

index 29c26f7..1528f38 100644 (file)
@@ -32,7 +32,7 @@ typedef enum
     GNSS_CMD_MAX
 } gnss_cfg_cmd_type_t;
 
-void do_gnss_cmd(int cmd,uint8_t *buffer,uint32_t size);
+int32_t do_gnss_cmd(int cmd,uint8_t *buffer,uint32_t size);
 
 void gnss_receive_handler(uint8_t *buffer, int32_t size);
 
index 6fe4e81..ac30715 100644 (file)
@@ -24,6 +24,7 @@
 #include "custom_utils.h"
 #include <dirent.h>
 #include <sys/stat.h>
+#include "cmsis_os2.h"
 // #include "gnss_sample.h"
 
 #define PGNSS_DATA_PATH          "/user/userdata/gnss"
@@ -61,6 +62,11 @@ static int g_is_listening_data = 0;  // 添加数据监听状态标志
 
 static char *pgnss_log = NULL;
 
+// GPS停止等待定时器相关变量
+static osTimerId_t g_stop_wait_timer = NULL;
+static int g_stop_wait_count = 0;
+static const int MAX_WAIT_COUNT = 8;  // 最多等待8秒 (80 * 100ms)
+
 // 全局变量,存储当前有效的时间戳文件夹路径
 static char *g_current_agnss_folder = NULL;
 
@@ -94,6 +100,11 @@ static void get_current_timestamp(char *timestamp_str, size_t max_len) {
     
     time(&rawtime);
     timeinfo = localtime(&rawtime);
+    if (timeinfo == NULL) {
+        printf("Error: localtime() returned NULL\n");
+        snprintf(timestamp_str, max_len, "1970-01-01 00:00:00");
+        return;
+    }
     
     snprintf(timestamp_str, max_len, "%04d-%02d-%02d %02d:%02d:%02d",
              timeinfo->tm_year + 1900,
@@ -111,6 +122,11 @@ static void get_current_timestamp_ms(char *timestamp_str, size_t max_len) {
     
     gettimeofday(&tv, NULL);
     timeinfo = localtime(&tv.tv_sec);
+    if (timeinfo == NULL) {
+        printf("Error: localtime() returned NULL\n");
+        snprintf(timestamp_str, max_len, "1970-01-01 00:00:00.000");
+        return;
+    }
     
     snprintf(timestamp_str, max_len, "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
              timeinfo->tm_year + 1900,
@@ -175,7 +191,7 @@ static int decode_nmea(char c)
     ret=0;
     if(nmea_decode(&g_nmeadata,c) ==1 ) ///调用解析函数
     {
-        dump_nmea_str(&(g_nmeadata.gpsParse));
+        // dump_nmea_str(&(g_nmeadata.gpsParse));
         if (g_nmeadata.gpsParse.sentence_type == GPS_SENTENCE_TH002 )
         {
             //一组数据最后一条
@@ -414,13 +430,17 @@ int32_t InjectPgnssWithFallbackToColdStart(tiot_handle handle)
 
     time(&rawtime);          // 获取UTC时间戳
     timeinfo = gmtime(&rawtime);  // 转换为UTC时间(无时区偏移)
-
-    utcTime.year = timeinfo->tm_year + 1900;
-    utcTime.month = timeinfo->tm_mon + 1;
-    utcTime.day = timeinfo->tm_mday;
-    utcTime.hour = timeinfo->tm_hour;
-    utcTime.minute = timeinfo->tm_min;
-    utcTime.second = timeinfo->tm_sec;
+    if (timeinfo == NULL) {
+        printf("Error: gmtime() returned NULL\n");
+        return 0;
+    } else {
+        utcTime.year = timeinfo->tm_year + 1900;
+        utcTime.month = timeinfo->tm_mon + 1;
+        utcTime.day = timeinfo->tm_mday;
+        utcTime.hour = timeinfo->tm_hour;
+        utcTime.minute = timeinfo->tm_min;
+        utcTime.second = timeinfo->tm_sec;
+    }
 
     printf("year[%d], mon[%d], day[%d], hour[%d], min[%d], sec[%d] \r\n",
     utcTime.year,utcTime.month,utcTime.day,
@@ -505,7 +525,8 @@ static void ListenGnssData(tiot_handle handle)
 {
     int32_t i = 0;
     int32_t timeout_count = 0;  // 连续超时计数器
-    
+    // char temp_buf[512] = {0};
+
     // 初始化GNSS服务缓冲区
     if (init_gnss_service_buffer() != 0) {
         printf("Error: Failed to initialize GNSS service buffer\n");
@@ -549,15 +570,20 @@ static void ListenGnssData(tiot_handle handle)
             
             uint16_t *type = (uint16_t *)g_gnssServiceBuff;
             if (type[0] == MSG_TYPE_ASCII) {
-
-                g_gnssServiceBuff[ret] = '\0';
+                // 确保ret在有效范围内再写入结束符
+                if (ret > 0 && ret < REPORT_MAX_BYTES) {
+                    g_gnssServiceBuff[ret] = '\0';
+                } else {
+                    printf("Error: Invalid ret value: %d, skipping this data\n", ret);
+                    continue;
+                }
                 
                 if (ret > MSG_CONTENT_IDX) {
                     char* pbuf = (char *)&g_gnssServiceBuff[MSG_CONTENT_IDX];
 
                     int str_len = strnlen(pbuf, ret - MSG_CONTENT_IDX);
                     if (str_len > 0) {
-                        printf("%s\r\n", pbuf);
+                        // printf("%s\r\n", pbuf);
 
                         if (g_is_pgnss_logon && g_gnssLogFp != NULL) {
                             int fprintf_result = fprintf(g_gnssLogFp, "%s\n", pbuf);
@@ -581,31 +607,32 @@ static void ListenGnssData(tiot_handle handle)
                         if (decode_nmea(pbuf[index])==1)
                         {
                         // dump_location_data(&g_global_gpsData);
-                        char *temp_buf = (char *)malloc(512);
-                        if (temp_buf == NULL) {
-                            printf("error: malloc temp_buf failed!\n");
-                            continue;
-                        }
-                        dump_location_data_to_buf(&g_global_gpsData, temp_buf, 512);
+                        // memset_s(temp_buf,sizeof(temp_buf),0,sizeof(temp_buf));
+                        // char *temp_buf = (char *)malloc(512);
+                        // if (temp_buf == NULL) {
+                        //     printf("error: malloc temp_buf failed!\n");
+                        //     continue;
+                        // }
+                        // dump_location_data_to_buf(&g_global_gpsData, temp_buf, 512);
                         
                         // printf("temp_buf : %s\n",temp_buf);
 
                         // 追加到pgnss_log中
-                        if (pgnss_log != NULL) {
-                            int current_len = strlen(pgnss_log);
-                            int data_len = strlen(temp_buf);
-                            if (current_len + data_len < 2047) {  // 留1字节给字符串结束符
-                                snprintf(pgnss_log + current_len, 2048 - current_len, "%s", temp_buf);
-                            } else {
-                                // 内存满了,清空从头开始存储
-                                printf("pgnss_log memory full, clearing and restarting\n");
-                                memset(pgnss_log, 0, 2048);
-                                snprintf(pgnss_log, 2048, "%s", temp_buf);
-                            }
-                        }
+                        // if (pgnss_log != NULL) {
+                        //     int current_len = strlen(pgnss_log);
+                        //     int data_len = strlen(temp_buf);
+                        //     if (current_len + data_len < 2047) {  // 留1字节给字符串结束符
+                        //         snprintf(pgnss_log + current_len, 2048 - current_len, "%s", temp_buf);
+                        //     } else {
+                        //         // 内存满了,清空从头开始存储
+                        //         printf("pgnss_log memory full, clearing and restarting\n");
+                        //         memset(pgnss_log, 0, 2048);
+                        //         snprintf(pgnss_log, 2048, "%s", temp_buf);
+                        //     }
+                        // }
                         
-                        printf("decode_nmea done\r\n");
-                        free(temp_buf);
+                        // printf("decode_nmea done\r\n");
+                        // free(temp_buf);
                         }
                     }
                 }
@@ -650,33 +677,12 @@ static void ListenGnssData(tiot_handle handle)
     cleanup_gnss_service_buffer();
 }
 
-void PGnssServerStop(void)
+/**
+ * @brief 执行GPS停止后的清理工作
+ * 这个函数在定时器回调中调用,确保非阻塞执行
+ */
+static void do_gps_stop_cleanup(void)
 {
-    printf("PGnssServerStop: Attempting to stop GPS...\r\n");
-    
-    // 检查GPS是否已经启动
-    if (g_is_pgnss_poweron == 0) {
-        printf("PGnssServerStop: GPS is not powered on, nothing to stop\r\n");
-        return;
-    }
-
-    // 等待数据监听停止(最多等待6秒)
-    int wait_count = 0;
-    const int max_wait_ms = 8000;
-    const int check_interval_ms = 100;
-    
-    while (g_is_listening_data == 0 && wait_count < (max_wait_ms / check_interval_ms)) {
-        LOS_Msleep(check_interval_ms);
-        wait_count++;
-        if (wait_count % 2 == 0) {
-            printf("PGnssServerStop: Waiting for data listening to stop... (%d/%d)\r\n", 
-                   wait_count * check_interval_ms, max_wait_ms);
-        }
-    }
-    
-    // 设置停止标志
-    g_pgnss_stopflag = 1;
-    
     // 如果当前正在下载星历,关闭下载服务
     printf("PGnssServerStop: Checking and stopping AGNSS download service...\r\n");
     uapi_gnss_http_server_deinit();
@@ -690,10 +696,122 @@ void PGnssServerStop(void)
     
     // 清理GNSS服务缓冲区
     cleanup_gnss_service_buffer();
+
+    memset_s(&g_global_gpsData,sizeof(g_global_gpsData),0,sizeof(g_global_gpsData));
+    memset_s(&g_nmeadata,sizeof(g_nmeadata),0,sizeof(g_nmeadata));
     
     printf("PGnssServerStop: Force stop completed\r\n");
 }
 
+/**
+ * @brief GPS停止等待定时器回调函数
+ * 每100ms检查一次数据监听状态,如果已停止或超时则执行清理
+ */
+static void gps_stop_wait_timer_callback(int data)
+{
+    g_stop_wait_count++;
+    
+    // 检查数据监听是否已停止
+    if (g_is_listening_data == 1) {
+        printf("PGnssServerStop: GPS has initialized and is listening, executing safe cleanup...\r\n");
+        
+        // 停止定时器
+        if (g_stop_wait_timer != NULL) {
+            osTimerStop(g_stop_wait_timer);
+            osTimerDelete(g_stop_wait_timer);
+            g_stop_wait_timer = NULL;
+        }
+        
+        // 执行清理工作
+        // do_gps_stop_cleanup();
+        // 设置停止标志
+        g_pgnss_stopflag = 1;
+        g_stop_wait_count = 0;
+        return;
+    }
+    
+    // 打印等待进度(每1秒打印一次)
+    if (g_stop_wait_count % 2 == 0) {
+        printf("PGnssServerStop: Waiting for data listening to stop... (%d/%d s)\r\n", 
+               g_stop_wait_count * 2, MAX_WAIT_COUNT * 2);
+    }
+    
+    // 超时处理:如果等待时间超过最大值,强制执行清理
+    if (g_stop_wait_count >= MAX_WAIT_COUNT) {
+        printf("PGnssServerStop: Timeout reached, forcing cleanup...\r\n");
+        
+        // 停止定时器
+        if (g_stop_wait_timer != NULL) {
+            osTimerStop(g_stop_wait_timer);
+            osTimerDelete(g_stop_wait_timer);
+            g_stop_wait_timer = NULL;
+        }
+        
+        // 强制执行清理工作
+
+        do_gps_stop_cleanup();
+        // 设置停止标志
+        g_pgnss_stopflag = 1;
+        g_stop_wait_count = 0;
+    }
+}
+
+void PGnssServerStop(void)
+{
+    printf("PGnssServerStop: Attempting to stop GPS...\r\n");
+    
+    // 检查GPS是否已经启动
+    if (g_is_pgnss_poweron == 0) {
+        printf("PGnssServerStop: GPS is not powered on, nothing to stop\r\n");
+        return;
+    }
+
+    // 如果数据监听已经停止,直接执行清理
+    if (g_is_listening_data == 1) {
+        printf("PGnssServerStop: Data listening already stopped, executing cleanup immediately\r\n");
+        // do_gps_stop_cleanup();
+        // 设置停止标志
+        g_pgnss_stopflag = 1;
+        return;
+    }
+    
+    // 如果定时器已存在,先停止并删除
+    if (g_stop_wait_timer != NULL) {
+        osTimerStop(g_stop_wait_timer);
+        osTimerDelete(g_stop_wait_timer);
+        g_stop_wait_timer = NULL;
+    }
+    
+    // 重置等待计数
+    g_stop_wait_count = 0;
+    
+    // 创建周期性定时器(每100ms检查一次)
+    g_stop_wait_timer = osTimerNew((osTimerFunc_t)gps_stop_wait_timer_callback, 
+                                    osTimerPeriodic, NULL, NULL);
+    if (g_stop_wait_timer == NULL) {
+        printf("PGnssServerStop: Failed to create wait timer, executing cleanup immediately\r\n");
+        // do_gps_stop_cleanup();
+        // 设置停止标志
+        g_pgnss_stopflag = 1;
+        return;
+    }
+    
+    // 启动定时器(1000ms间隔)
+    int tick = osMs2Tick(1000);
+    osStatus_t ret = osTimerStart(g_stop_wait_timer, tick);
+    if (ret != osOK) {
+        printf("PGnssServerStop: Failed to start wait timer (ret=%d), executing cleanup immediately\r\n", ret);
+        osTimerDelete(g_stop_wait_timer);
+        g_stop_wait_timer = NULL;
+        // do_gps_stop_cleanup();
+        // 设置停止标志
+        g_pgnss_stopflag = 1;
+        return;
+    }
+    
+    printf("PGnssServerStop: Started non-blocking wait timer, cleanup will execute when ready\r\n");
+}
+
 int getPGnssServerStat(void)
 {
     return g_is_pgnss_poweron;
@@ -749,10 +867,10 @@ void PGnssServerStartAutoModeStart(void)
         g_is_pgnss_poweron = 0;
         g_is_pgnss_start = 0;
         g_pgnss_stopflag = 1;
-        if (pgnss_log != NULL) {
-            free(pgnss_log);
-            pgnss_log = NULL;
-        }
+        // if (pgnss_log != NULL) {
+        //     free(pgnss_log);
+        //     pgnss_log = NULL;
+        // }
         return;
     }
 
@@ -762,10 +880,10 @@ void PGnssServerStartAutoModeStart(void)
         g_gnssLogFp = fopen("/user/userdata/gnsslog.txt", "w");
         if (g_gnssLogFp == NULL) {
             printf("error: open log file error\n");
-            if (pgnss_log != NULL) {
-                free(pgnss_log);
-                pgnss_log = NULL;
-            }
+            // if (pgnss_log != NULL) {
+            //     free(pgnss_log);
+            //     pgnss_log = NULL;
+            // }
             return;
         }
         // 写入日志开启时间戳
@@ -781,10 +899,10 @@ void PGnssServerStartAutoModeStart(void)
         g_is_pgnss_poweron = 0;
         g_is_pgnss_start = 0;
         g_pgnss_stopflag = 1;
-        if (pgnss_log != NULL) {
-            free(pgnss_log);
-            pgnss_log = NULL;
-        }
+        // if (pgnss_log != NULL) {
+        //     free(pgnss_log);
+        //     pgnss_log = NULL;
+        // }
         return;
     }
     printf("open tiot service success for auto start\n");
@@ -854,11 +972,11 @@ void PGnssServerStartAutoModeStart(void)
     
 
     // 释放pgnss_log内存
-    if (pgnss_log != NULL) {
-        printf("gnss_log: %s\r\n", pgnss_log);
-        free(pgnss_log);
-        pgnss_log = NULL;
-    }
+    // if (pgnss_log != NULL) {
+    //     printf("gnss_log: %s\r\n", pgnss_log);
+    //     free(pgnss_log);
+    //     pgnss_log = NULL;
+    // }
 }
 
 // 辅助函数:检查指定文件夹的文件数量
@@ -903,8 +1021,16 @@ static int check_agnss_folder_expired(void)
     // 检查内存分配是否成功
     if (candidate_folder_path == NULL || candidate_folder_name == NULL) {
         printf("ERROR: Failed to allocate memory for candidate folder variables\n");
-        if (candidate_folder_path != NULL) free(candidate_folder_path);
-        if (candidate_folder_name != NULL) free(candidate_folder_name);
+        if (candidate_folder_path != NULL) 
+        {
+            free(candidate_folder_path);
+            candidate_folder_path = NULL;
+        }
+        if (candidate_folder_name != NULL) 
+        {
+            free(candidate_folder_name);
+            candidate_folder_name = NULL;
+        }
         closedir(dir);
         return 1;
     }
@@ -930,12 +1056,14 @@ static int check_agnss_folder_expired(void)
             uint32_t time_diff = 0;
             if (current_timestamp >= folder_timestamp) {
                 time_diff = current_timestamp - folder_timestamp;
-            } else {
-                time_diff = folder_timestamp - current_timestamp;
-            }
-            
+            } 
+            // else {
+            //     time_diff = folder_timestamp - current_timestamp;
+            // }
+            // printf("current_timestamp:%d,folder_timestamp:%d,time_diff : %d\n",current_timestamp,folder_timestamp,time_diff);
             // 检查是否在24小时内
-            if (time_diff < 86400) { // 24小时 = 86400秒
+            if (time_diff < 86400 && time_diff > 0) // 24小时 = 86400秒
+            { 
                 // 构建完整路径以检查文件数量
                 char full_folder_path[512];
                 int path_ret = snprintf(full_folder_path, sizeof(full_folder_path), "%s/%s", PGNSS_DATA_PATH, entry->d_name);
@@ -954,27 +1082,27 @@ static int check_agnss_folder_expired(void)
                 // 检查文件数量是否为26个
                 if (file_count >= 20) {
                     found_valid_folder = 1;
-                    if (time_diff < min_time_diff) {
-                        min_time_diff = time_diff;
-                        // 更新全局变量,存储最接近的时间戳文件夹路径
-                        if (g_current_agnss_folder != NULL) {
-                            free(g_current_agnss_folder);
-                            g_current_agnss_folder = NULL;
-                        }
-                        g_current_agnss_folder = malloc(256);
-                        if (g_current_agnss_folder != NULL) {
-                            int ret = snprintf(g_current_agnss_folder, 256, "%s/%s", PGNSS_DATA_PATH, entry->d_name);
-                            if (ret < 0 || ret >= 256) {
-                                printf("ERROR: snprintf failed or buffer overflow for g_current_agnss_folder\n");
+                        if (time_diff < min_time_diff) {
+                            min_time_diff = time_diff;
+                            // 更新全局变量,存储最接近的时间戳文件夹路径
+                            if (g_current_agnss_folder != NULL) {
                                 free(g_current_agnss_folder);
                                 g_current_agnss_folder = NULL;
                             }
-                        } else {
-                            printf("ERROR: Failed to allocate memory for g_current_agnss_folder\n");
+                            g_current_agnss_folder = malloc(256);
+                            if (g_current_agnss_folder != NULL) {
+                                int ret = snprintf(g_current_agnss_folder, 256, "%s/%s", PGNSS_DATA_PATH, entry->d_name);
+                                if (ret < 0 || ret >= 256) {
+                                    printf("ERROR: snprintf failed or buffer overflow for g_current_agnss_folder\n");
+                                    free(g_current_agnss_folder);
+                                    g_current_agnss_folder = NULL;
+                                }
+                            } else {
+                                printf("ERROR: Failed to allocate memory for g_current_agnss_folder\n");
+                            }
                         }
-                    }
-                    printf("Found valid AGNSS folder: %s (time diff: %u seconds, file count: %d)\n", 
-                           entry->d_name, time_diff, file_count);
+                        printf("Found valid AGNSS folder: %s (time diff: %u seconds, file count: %d)\n", 
+                               entry->d_name, time_diff, file_count);
                 } else {
                     printf("Found AGNSS folder with invalid file count: %s (time diff: %u seconds, file count: %d/26)\n", 
                            entry->d_name, time_diff, file_count);
@@ -1001,7 +1129,9 @@ static int check_agnss_folder_expired(void)
     // 如果找到了完整的有效文件夹,直接返回
     if (found_valid_folder) {
         free(candidate_folder_path);
+        candidate_folder_path = NULL;
         free(candidate_folder_name);
+        candidate_folder_name = NULL;
         return 0; // 未过期
     }
     
@@ -1024,7 +1154,8 @@ static int check_agnss_folder_expired(void)
             printf("Cycle %d: Checking %s - file count: %d/26\n", 
                    current_cycle, candidate_folder_name, file_count);
             
-            if (file_count == 26) {
+            if (file_count >= 20) 
+            {
                 printf("SUCCESS: AGNSS folder now has 26 files! %s\n", candidate_folder_name);
                 
                 // 更新全局变量,存储有效的文件夹路径
@@ -1040,18 +1171,24 @@ static int check_agnss_folder_expired(void)
                         free(g_current_agnss_folder);
                         g_current_agnss_folder = NULL;
                         free(candidate_folder_path);
+                        candidate_folder_path = NULL;
                         free(candidate_folder_name);
+                        candidate_folder_name = NULL;
                         return 1; // 失败
                     }
                 } else {
                     printf("ERROR: Failed to allocate memory for g_current_agnss_folder\n");
                     free(candidate_folder_path);
+                    candidate_folder_path = NULL;
                     free(candidate_folder_name);
+                    candidate_folder_name = NULL;
                     return 1; // 失败
                 }
                 
                 free(candidate_folder_path);
+                candidate_folder_path = NULL;
                 free(candidate_folder_name);
+                candidate_folder_name = NULL;
                 return 0; // 未过期,文件已完整
             }
             
@@ -1068,7 +1205,9 @@ static int check_agnss_folder_expired(void)
     
     printf("No valid AGNSS folder found within 24 hours with 26 files\n");
     free(candidate_folder_path);
+    candidate_folder_path = NULL;
     free(candidate_folder_name);
+    candidate_folder_name = NULL;
     return 1; // 过期
 }
 
@@ -1216,15 +1355,15 @@ void PGnssServerStart(void)
 
     printf("\nenter gnss samples\r\n");
     
-    if (pgnss_log == NULL) 
-    {
-        pgnss_log = (char *)malloc(2048);
-        if (pgnss_log == NULL) {
-            printf("error: malloc pgnss_log failed!\n");
-            return;
-        }
-        memset(pgnss_log, 0, 2048);
-    }
+    // if (pgnss_log == NULL) 
+    // {
+    //     pgnss_log = (char *)malloc(2048);
+    //     if (pgnss_log == NULL) {
+    //         printf("error: malloc pgnss_log failed!\n");
+    //         return;
+    //     }
+    //     memset(pgnss_log, 0, 2048);
+    // }
 
 
     uapi_pm_add_sleep_veto(PM_ID_SYS);
@@ -1250,10 +1389,10 @@ void PGnssServerStart(void)
         g_is_pgnss_poweron = 0;
         g_is_pgnss_start = 0;
         g_pgnss_stopflag = 1;
-        if (pgnss_log != NULL) {
-            free(pgnss_log);
-            pgnss_log = NULL;
-        }
+        // if (pgnss_log != NULL) {
+        //     free(pgnss_log);
+        //     pgnss_log = NULL;
+        // }
         return;
     }
 
@@ -1263,10 +1402,10 @@ void PGnssServerStart(void)
         g_gnssLogFp = fopen("/user/userdata/gnsslog.txt", "w");
         if (g_gnssLogFp == NULL) {
             printf("error: open log file error\n");
-            if (pgnss_log != NULL) {
-                free(pgnss_log);
-                pgnss_log = NULL;
-            }
+            // if (pgnss_log != NULL) {
+            //     free(pgnss_log);
+            //     pgnss_log = NULL;
+            // }
             return;
         }
         // 写入日志开启时间戳
@@ -1283,10 +1422,10 @@ void PGnssServerStart(void)
         g_is_pgnss_start = 0;
         g_pgnss_stopflag = 1;
         g_cold_start_pgnss_stopflag = 1;
-        if (pgnss_log != NULL) {
-            free(pgnss_log);
-            pgnss_log = NULL;
-        }
+        // if (pgnss_log != NULL) {
+        //     free(pgnss_log);
+        //     pgnss_log = NULL;
+        // }
         return;
     }
     printf("open tiot service success\r\n");
@@ -1354,14 +1493,15 @@ void PGnssServerStart(void)
     uart_config_init();
 #endif
     printf("finish gnss samples\r\n");
-    
 
+    do_gps_stop_cleanup();
+    // 设置停止标志
     // 释放pgnss_log内存
-    if (pgnss_log != NULL) {
-        printf("pgnss_log:%s\r\n",pgnss_log);
-        free(pgnss_log);
-        pgnss_log = NULL;
-    }
+    // if (pgnss_log != NULL) {
+    //     printf("pgnss_log:%s\r\n",pgnss_log);
+    //     free(pgnss_log);
+    //     pgnss_log = NULL;
+    // }
     if(g_cold_start_pgnss_stopflag == 1)
     {
         PGnssServerStartAutoModeStart();
index 46bd78f..0c67d06 100644 (file)
@@ -144,6 +144,11 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata)
     // handle the last term in a message\r
     if (pnmea->is_checksum_term)\r
        {\r
+        // 检查校验和字段长度,防止数组越界访问\r
+        if (pnmea->term_offset < 2) {\r
+            // 校验和字段长度不足,返回0表示解析失败\r
+            return 0;\r
+        }\r
         unsigned char checksum = 16 * from_hex(pnmea->term[0]) + from_hex(pnmea->term[1]);\r
         \r
         /* 检验信息段是否完整无错,如果校验通过,则将解析得到的数据保存,并提供给用户调用*/\r
@@ -235,7 +240,7 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata)
                                                // }\r
                                                // pdata->starcount = pnmea->starcount;\r
                                                add_start_to_gpsbuf(pnmea,pdata);\r
-                                               printf("gsv starcount copy to pdata \r\n");\r
+                                               // printf("gsv starcount copy to pdata \r\n");\r
                                                \r
                                                break;\r
                                        case GPS_SENTENCE_GLL:\r
@@ -247,7 +252,7 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata)
                                        case GPS_SENTENCE_TH000:\r
                                                pdata->th000_signal_vga = pnmea->th000_signal_vga;\r
                            pdata->last_gps_time_ms = now;\r
-                                               printf("th000 copy to pdata \r\n" );\r
+                                               // printf("th000 copy to pdata \r\n" );\r
                                                break;\r
                                        case GPS_SENTENCE_TH001:\r
                                                pdata->th001_errorcode = pnmea->th001_errorcode;\r
@@ -255,7 +260,7 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata)
                                                pdata->th001_trace_star_count = pnmea->th001_trace_star_count;\r
                                                pdata->th001_valid_star_count = pnmea->th001_valid_star_count;\r
                            pdata->last_gps_time_ms = now;\r
-                                               printf("th001 copy to pdata \r\n" );\r
+                                               // printf("th001 copy to pdata \r\n" );\r
                                        case GPS_SENTENCE_TH002:\r
                            pdata->last_gps_time_ms = now;\r
                                                break;\r
@@ -370,17 +375,17 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata)
             break;\r
                case GPS_SENTENCE_GSV + 1: // GSV numMsg 2 GSV 语句总数。\r
                        pnmea->gsvpagecount =  (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv pagecount %d\r\n",pnmea->gsvpagecount );\r
+                       // printf("gsv pagecount %d\r\n",pnmea->gsvpagecount );\r
                        pnmea->gps_data_good=1;\r
                        break;\r
                case GPS_SENTENCE_GSV + 2: // GSV msgNo GSV 语句编号。\r
                        pnmea->gsvpage =  (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv gsvpage %d\r\n",pnmea->gsvpage );\r
+                       // printf("gsv gsvpage %d\r\n",pnmea->gsvpage );\r
                        break;\r
                case GPS_SENTENCE_GSV + 3: // GSV numSV 可见卫星总数。\r
                        {\r
                                pnmea->starcount =  (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                               printf("gsv starcount %d\r\n",pnmea->starcount );\r
+                               // printf("gsv starcount %d\r\n",pnmea->starcount );\r
                                if (pnmea->gsvpage==pnmea->gsvpagecount)\r
                                {       //最后一页星的数量\r
                                        //非最后一页的中间任意一页一定是4颗星\r
@@ -394,48 +399,48 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata)
                case GPS_SENTENCE_GSV + 4: // GSV svid  卫星编号\r
                        startindex=4*(pnmea->gsvpage-1);\r
                        pnmea->starts[0].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv 0 startindex %d startid %d\r\n",startindex ,pnmea->starts[0].starID);\r
+                       // printf("gsv 0 startindex %d startid %d\r\n",startindex ,pnmea->starts[0].starID);\r
                        break;\r
                case GPS_SENTENCE_GSV + 7: // GSV cn0 载噪比:0~99,无效时为空\r
                        startindex=4*(pnmea->gsvpage-1);\r
                        pnmea->starts[0].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv 0 startindex %d snr %d\r\n",startindex ,pnmea->starts[0].snr);\r
+                       // printf("gsv 0 startindex %d snr %d\r\n",startindex ,pnmea->starts[0].snr);\r
                        break;\r
                case GPS_SENTENCE_GSV + 8: // GSV svid  卫星编号 N*4\r
                        startindex=4*(pnmea->gsvpage-1)+1;\r
                        if (1>=pnmea->gsvpage_starcount) break;\r
                        pnmea->starts[1].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv 1 startindex %d startid %d\r\n",startindex ,pnmea->starts[1].starID);\r
+                       // printf("gsv 1 startindex %d startid %d\r\n",startindex ,pnmea->starts[1].starID);\r
                        break;\r
                case GPS_SENTENCE_GSV + 11: // GSV cn0 载噪比:0~99,无效时为空\r
                        startindex=4*(pnmea->gsvpage-1)+1;\r
                        if (1>=pnmea->gsvpage_starcount) break;\r
                        pnmea->starts[1].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv 1 startindex %d snr %d\r\n",startindex ,pnmea->starts[1].snr);\r
+                       // printf("gsv 1 startindex %d snr %d\r\n",startindex ,pnmea->starts[1].snr);\r
                        break;\r
                case GPS_SENTENCE_GSV + 12: // GSV svid  卫星编号\r
                        startindex=4*(pnmea->gsvpage-1)+2;\r
                        if (2>=pnmea->gsvpage_starcount) break;\r
                        pnmea->starts[2].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv 2 startindex %d startid %d\r\n",startindex ,pnmea->starts[2].starID);\r
+                       // printf("gsv 2 startindex %d startid %d\r\n",startindex ,pnmea->starts[2].starID);\r
                        break;\r
                case GPS_SENTENCE_GSV + 15: // GSV cn0 载噪比:0~99,无效时为空\r
                        startindex=4*(pnmea->gsvpage-1)+2;\r
                        if (2>=pnmea->gsvpage_starcount) break;\r
                        pnmea->starts[2].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv 2 startindex %d snr %d\r\n",startindex ,pnmea->starts[2].snr);\r
+                       // printf("gsv 2 startindex %d snr %d\r\n",startindex ,pnmea->starts[2].snr);\r
                        break;\r
                case GPS_SENTENCE_GSV + 16: // GSV svid  卫星编号\r
                        startindex=4*(pnmea->gsvpage-1)+3;\r
                        if (3>=pnmea->gsvpage_starcount) break;\r
                        pnmea->starts[3].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv 3 startindex %d startid %d\r\n",startindex ,pnmea->starts[3].starID);\r
+                       // printf("gsv 3 startindex %d startid %d\r\n",startindex ,pnmea->starts[3].starID);\r
                        break;\r
                case GPS_SENTENCE_GSV + 19: // GSV cn0 载噪比:0~99,无效时为空\r
                        startindex=4*(pnmea->gsvpage-1)+3;\r
                        if (3>=pnmea->gsvpage_starcount) break;\r
                        pnmea->starts[3].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("gsv 3 startindex %d snr %d\r\n",startindex ,pnmea->starts[3].snr);\r
+                       // printf("gsv 3 startindex %d snr %d\r\n",startindex ,pnmea->starts[3].snr);\r
                        break;\r
         // time and date\r
         //\r
@@ -493,7 +498,7 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata)
             break;\r
                case GPS_SENTENCE_TH000 + 1:/*VGA 档位(第 2 字段)描述了当前的信号增益档位,有效范围为2~13,正常信号时,其档位值为 7~9;如果档位值显示为 2,说明可能存在强干扰,导致增益饱和;如果档位值为 13,说明信号特别弱,可能射频链路增益不足*/\r
                        pnmea->th000_signal_vga = (unsigned int)sring_to_int((const char*)pnmea->term, (void*)0);\r
-                       printf("th000 signal_vga %d,%s\n",pnmea->th000_signal_vga,pnmea->term);\r
+                       // printf("th000 signal_vga %d,%s\n",pnmea->th000_signal_vga,pnmea->term);\r
                        pnmea->gps_data_good = 1;\r
             break;\r
                case GPS_SENTENCE_TH001 + 4:\r
@@ -1419,7 +1424,7 @@ void dump_location_data(gps_data_t*locationdata)
        char* msgbuf=(char*)malloc(MSGBUF_LEN);\r
        if (msgbuf == NULL) return ;\r
        dump_location_data_to_buf(locationdata,msgbuf,MSGBUF_LEN);\r
-       printf("%s",msgbuf);\r
+       // printf("%s",msgbuf);\r
        free(msgbuf);\r
 }\r
 \r
index b45018b..0889589 100644 (file)
@@ -65,14 +65,14 @@ int decode_nmea(char c)
         // printf("%c",c);
     if(nmea_decode(&g_nmeadata,c) ==1) ///调用解析函数
     {
-        printf("%s\r\n",tmpbuf);
+        // printf("%s\r\n",tmpbuf);
         memset(tmpbuf,0,sizeof(tmpbuf));
         count=0;
         dump_nmea_str(&(g_nmeadata.gpsParse));
         if (g_nmeadata.gpsParse.sentence_type == GPS_SENTENCE_TH002)
         {
             //一组数据最后一条
-            dump_location_data(&(g_nmeadata.gpsData));
+            // dump_location_data(&(g_nmeadata.gpsData));
             memset(&g_nmeadata,0,sizeof(g_nmeadata));
         }
     } 
index 1c3a432..93e3a0e 100644 (file)
@@ -123,16 +123,20 @@ errcode_t gnss_start(void)
 {
     // do_gnss_cmd(GNSS_CMD_WRITEDATA,g_cfg_all_nmea_cmd,sizeof(g_cfg_all_nmea_cmd)); 
     uint8_t cmd = GNSS_CMD_START;
-    do_gnss_cmd(GNSS_CMD_WRITEDATA, &cmd,1);
+    int32_t ret = do_gnss_cmd(GNSS_CMD_WRITEDATA, &cmd, 1);
+    if (ret != ERRCODE_SUCC) {
+        PRINT("gnss_start queue cmd failed, ret %d\n", ret);
+        return ret;
+    }
     g_gnss_status = 1;
-    return 0;
+    return ERRCODE_SUCC;
 }
 
 errcode_t gnss_stop(void)
 {
     // uint8_t cmd = GNSS_CMD_STOP;
     // do_gnss_cmd(GNSS_CMD_WRITEDATA, &cmd,1);
-    // g_gnss_status = 0;
+    g_gnss_status = 0;
     // GnssServerStop();
     PGnssServerStop();
     return 0;
index 33a073b..24a54df 100644 (file)
@@ -75,14 +75,14 @@ void do_gnss_cmd_head(int cmd,uint8_t *buffer,uint32_t size)
     }
     
 }
-void do_gnss_cmd(int cmd,uint8_t *buffer,uint32_t size)
+int32_t do_gnss_cmd(int cmd,uint8_t *buffer,uint32_t size)
 {
     int ret;
 
     if (buffer == NULL || size == 0 ) 
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"input buffer is NULL or size == 0"NEWLINE );
-        return ;
+        return ERRCODE_FAIL;
     }
     gnss_cmd_t mail = {0};
     if(cmd == GNSS_CMD_READDATA)
@@ -90,7 +90,7 @@ void do_gnss_cmd(int cmd,uint8_t *buffer,uint32_t size)
         mail.buffer = osal_kmalloc(size+1, OSAL_GFP_KERNEL);
         if (mail.buffer == NULL) {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"uart message buffer memory alloc fail, length is %d "NEWLINE, size);
-            return;
+            return ERRCODE_FAIL;
         }
         memset_s(mail.buffer,size+1,0,size+1);
         memcpy_s(mail.buffer,MAX_BUFFER_SIZE,buffer,size);
@@ -107,8 +107,13 @@ void do_gnss_cmd(int cmd,uint8_t *buffer,uint32_t size)
                                     sizeof(gnss_cmd_t), 0);
     if (ret != OSAL_SUCCESS) {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"Error gnss cmd msg %d send failed! err=0x%02X!"NEWLINE,cmd, ret);
+        if ((cmd == GNSS_CMD_READDATA) && (mail.buffer != NULL)) {
+            osal_kfree(mail.buffer);
+            mail.buffer = NULL;
+        }
+        return ret;
     }
-    
+    return ERRCODE_SUCC;
 }
 
 uint32_t gnss_write_cmd(uint8_t * cmdbuf,uint16_t cmdlen)
@@ -147,12 +152,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 +171,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,36 +184,50 @@ 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();
+                    if (is_gnss_on()) {
+                        PGnssServerStart();
+                    } else {
+                        WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,
+                                      "drop stale GNSS_CMD_START because gnss_status=0\r\n");
+                    }
                     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);
             }
         }
-        if(mail.cmd == GNSS_CMD_READDATA)
+        if ((mail.cmd == GNSS_CMD_READDATA) && (mail.buffer != NULL)) {
             osal_kfree(mail.buffer); //只有接收的缓存需要free,发送的都是静态数组,无需申请缓存
+            mail.buffer = NULL;
+        }
     }
 }
 
@@ -214,12 +236,12 @@ void gnss_receive_handler(uint8_t *buffer, int32_t size)
        // WEARABLE_LOGD(WEARABLE_LOG_MODULE_MAIN_SERVICE,"gnss_receive_handler %d \n",size);
     if (g_gnss_cmd_queue!= 0xFFFFFFFF)
     {
-        do_gnss_cmd(GNSS_CMD_READDATA,buffer,size);
+        (void)do_gnss_cmd(GNSS_CMD_READDATA,buffer,size);
     }  
 }
 
 #define GNSS_CMD_TASK_MSG_COUNT 128
-#define GNSS_CMD_TASK_SIZE (0x2500)
+#define GNSS_CMD_TASK_SIZE (0x3000)
 #define GNSS_CMD_TASK_PRIO 4
 void create_gnss_uart_queue(void)
 {
@@ -238,7 +260,7 @@ int gnss_uart_init(void)
     app_task_definition_t taskcfg={0};
     taskcfg.create_queue_handle = create_gnss_uart_queue;
     taskcfg.attr.name="uart_gnss_service";
-    taskcfg.attr.priority = osPriorityHigh;//osPriorityNormal; GUI osPriorityAboveNormal2
+    taskcfg.attr.priority = osPriorityAboveNormal2;//osPriorityNormal; GUI osPriorityAboveNormal2
     taskcfg.attr.stack_size = GNSS_CMD_TASK_SIZE;
     taskcfg.func = uart_event_task;
     taskcfg.use_mem = USE_EXTEND_MEM;