From 65f66b69bf4f809b567f6d9fffd4cc00058895c4 Mon Sep 17 00:00:00 2001 From: luozheng <1732036298@qq.com> Date: Wed, 15 Apr 2026 17:21:53 +0800 Subject: [PATCH] =?utf8?q?GPS=E5=90=88=E5=B9=B6=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- code/sdk/zhihui/services/gnss/inc/uart_gnss.h | 2 +- .../gnss/sample/pgnss_sample/pgnss_sample.c | 394 ++++++++++++------ code/sdk/zhihui/services/gnss/src/NMEA0183.c | 37 +- .../sdk/zhihui/services/gnss/src/decodenmea.c | 4 +- code/sdk/zhihui/services/gnss/src/gnss_ctl.c | 10 +- code/sdk/zhihui/services/gnss/src/uart_gnss.c | 50 ++- 6 files changed, 334 insertions(+), 163 deletions(-) diff --git a/code/sdk/zhihui/services/gnss/inc/uart_gnss.h b/code/sdk/zhihui/services/gnss/inc/uart_gnss.h index 29c26f72c..1528f3830 100644 --- a/code/sdk/zhihui/services/gnss/inc/uart_gnss.h +++ b/code/sdk/zhihui/services/gnss/inc/uart_gnss.h @@ -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); diff --git a/code/sdk/zhihui/services/gnss/sample/pgnss_sample/pgnss_sample.c b/code/sdk/zhihui/services/gnss/sample/pgnss_sample/pgnss_sample.c index 6fe4e81fc..ac3071593 100644 --- a/code/sdk/zhihui/services/gnss/sample/pgnss_sample/pgnss_sample.c +++ b/code/sdk/zhihui/services/gnss/sample/pgnss_sample/pgnss_sample.c @@ -24,6 +24,7 @@ #include "custom_utils.h" #include #include +#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(); diff --git a/code/sdk/zhihui/services/gnss/src/NMEA0183.c b/code/sdk/zhihui/services/gnss/src/NMEA0183.c index 46bd78f2d..0c67d06e7 100644 --- a/code/sdk/zhihui/services/gnss/src/NMEA0183.c +++ b/code/sdk/zhihui/services/gnss/src/NMEA0183.c @@ -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 if (pnmea->is_checksum_term) { + // 检查校验和字段长度,防止数组越界访问 + if (pnmea->term_offset < 2) { + // 校验和字段长度不足,返回0表示解析失败 + return 0; + } unsigned char checksum = 16 * from_hex(pnmea->term[0]) + from_hex(pnmea->term[1]); /* 检验信息段是否完整无错,如果校验通过,则将解析得到的数据保存,并提供给用户调用*/ @@ -235,7 +240,7 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata) // } // pdata->starcount = pnmea->starcount; add_start_to_gpsbuf(pnmea,pdata); - printf("gsv starcount copy to pdata \r\n"); + // printf("gsv starcount copy to pdata \r\n"); break; case GPS_SENTENCE_GLL: @@ -247,7 +252,7 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata) case GPS_SENTENCE_TH000: pdata->th000_signal_vga = pnmea->th000_signal_vga; pdata->last_gps_time_ms = now; - printf("th000 copy to pdata \r\n" ); + // printf("th000 copy to pdata \r\n" ); break; case GPS_SENTENCE_TH001: pdata->th001_errorcode = pnmea->th001_errorcode; @@ -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; pdata->th001_valid_star_count = pnmea->th001_valid_star_count; pdata->last_gps_time_ms = now; - printf("th001 copy to pdata \r\n" ); + // printf("th001 copy to pdata \r\n" ); case GPS_SENTENCE_TH002: pdata->last_gps_time_ms = now; break; @@ -370,17 +375,17 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata) break; case GPS_SENTENCE_GSV + 1: // GSV numMsg 2 GSV 语句总数。 pnmea->gsvpagecount = (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv pagecount %d\r\n",pnmea->gsvpagecount ); + // printf("gsv pagecount %d\r\n",pnmea->gsvpagecount ); pnmea->gps_data_good=1; break; case GPS_SENTENCE_GSV + 2: // GSV msgNo GSV 语句编号。 pnmea->gsvpage = (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv gsvpage %d\r\n",pnmea->gsvpage ); + // printf("gsv gsvpage %d\r\n",pnmea->gsvpage ); break; case GPS_SENTENCE_GSV + 3: // GSV numSV 可见卫星总数。 { pnmea->starcount = (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv starcount %d\r\n",pnmea->starcount ); + // printf("gsv starcount %d\r\n",pnmea->starcount ); if (pnmea->gsvpage==pnmea->gsvpagecount) { //最后一页星的数量 //非最后一页的中间任意一页一定是4颗星 @@ -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 卫星编号 startindex=4*(pnmea->gsvpage-1); pnmea->starts[0].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv 0 startindex %d startid %d\r\n",startindex ,pnmea->starts[0].starID); + // printf("gsv 0 startindex %d startid %d\r\n",startindex ,pnmea->starts[0].starID); break; case GPS_SENTENCE_GSV + 7: // GSV cn0 载噪比:0~99,无效时为空 startindex=4*(pnmea->gsvpage-1); pnmea->starts[0].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv 0 startindex %d snr %d\r\n",startindex ,pnmea->starts[0].snr); + // printf("gsv 0 startindex %d snr %d\r\n",startindex ,pnmea->starts[0].snr); break; case GPS_SENTENCE_GSV + 8: // GSV svid 卫星编号 N*4 startindex=4*(pnmea->gsvpage-1)+1; if (1>=pnmea->gsvpage_starcount) break; pnmea->starts[1].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv 1 startindex %d startid %d\r\n",startindex ,pnmea->starts[1].starID); + // printf("gsv 1 startindex %d startid %d\r\n",startindex ,pnmea->starts[1].starID); break; case GPS_SENTENCE_GSV + 11: // GSV cn0 载噪比:0~99,无效时为空 startindex=4*(pnmea->gsvpage-1)+1; if (1>=pnmea->gsvpage_starcount) break; pnmea->starts[1].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv 1 startindex %d snr %d\r\n",startindex ,pnmea->starts[1].snr); + // printf("gsv 1 startindex %d snr %d\r\n",startindex ,pnmea->starts[1].snr); break; case GPS_SENTENCE_GSV + 12: // GSV svid 卫星编号 startindex=4*(pnmea->gsvpage-1)+2; if (2>=pnmea->gsvpage_starcount) break; pnmea->starts[2].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv 2 startindex %d startid %d\r\n",startindex ,pnmea->starts[2].starID); + // printf("gsv 2 startindex %d startid %d\r\n",startindex ,pnmea->starts[2].starID); break; case GPS_SENTENCE_GSV + 15: // GSV cn0 载噪比:0~99,无效时为空 startindex=4*(pnmea->gsvpage-1)+2; if (2>=pnmea->gsvpage_starcount) break; pnmea->starts[2].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv 2 startindex %d snr %d\r\n",startindex ,pnmea->starts[2].snr); + // printf("gsv 2 startindex %d snr %d\r\n",startindex ,pnmea->starts[2].snr); break; case GPS_SENTENCE_GSV + 16: // GSV svid 卫星编号 startindex=4*(pnmea->gsvpage-1)+3; if (3>=pnmea->gsvpage_starcount) break; pnmea->starts[3].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv 3 startindex %d startid %d\r\n",startindex ,pnmea->starts[3].starID); + // printf("gsv 3 startindex %d startid %d\r\n",startindex ,pnmea->starts[3].starID); break; case GPS_SENTENCE_GSV + 19: // GSV cn0 载噪比:0~99,无效时为空 startindex=4*(pnmea->gsvpage-1)+3; if (3>=pnmea->gsvpage_starcount) break; pnmea->starts[3].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0); - printf("gsv 3 startindex %d snr %d\r\n",startindex ,pnmea->starts[3].snr); + // printf("gsv 3 startindex %d snr %d\r\n",startindex ,pnmea->starts[3].snr); break; // time and date // @@ -493,7 +498,7 @@ static unsigned char nmea_term_complete(gps_nmea_t* pnmea, gps_data_t* pdata) break; case GPS_SENTENCE_TH000 + 1:/*VGA 档位(第 2 字段)描述了当前的信号增益档位,有效范围为2~13,正常信号时,其档位值为 7~9;如果档位值显示为 2,说明可能存在强干扰,导致增益饱和;如果档位值为 13,说明信号特别弱,可能射频链路增益不足*/ pnmea->th000_signal_vga = (unsigned int)sring_to_int((const char*)pnmea->term, (void*)0); - printf("th000 signal_vga %d,%s\n",pnmea->th000_signal_vga,pnmea->term); + // printf("th000 signal_vga %d,%s\n",pnmea->th000_signal_vga,pnmea->term); pnmea->gps_data_good = 1; break; case GPS_SENTENCE_TH001 + 4: @@ -1419,7 +1424,7 @@ void dump_location_data(gps_data_t*locationdata) char* msgbuf=(char*)malloc(MSGBUF_LEN); if (msgbuf == NULL) return ; dump_location_data_to_buf(locationdata,msgbuf,MSGBUF_LEN); - printf("%s",msgbuf); + // printf("%s",msgbuf); free(msgbuf); } diff --git a/code/sdk/zhihui/services/gnss/src/decodenmea.c b/code/sdk/zhihui/services/gnss/src/decodenmea.c index b45018bf7..0889589b2 100644 --- a/code/sdk/zhihui/services/gnss/src/decodenmea.c +++ b/code/sdk/zhihui/services/gnss/src/decodenmea.c @@ -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)); } } diff --git a/code/sdk/zhihui/services/gnss/src/gnss_ctl.c b/code/sdk/zhihui/services/gnss/src/gnss_ctl.c index 1c3a432bb..93e3a0ebe 100644 --- a/code/sdk/zhihui/services/gnss/src/gnss_ctl.c +++ b/code/sdk/zhihui/services/gnss/src/gnss_ctl.c @@ -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; diff --git a/code/sdk/zhihui/services/gnss/src/uart_gnss.c b/code/sdk/zhihui/services/gnss/src/uart_gnss.c index 33a073bef..24a54dfef 100644 --- a/code/sdk/zhihui/services/gnss/src/uart_gnss.c +++ b/code/sdk/zhihui/services/gnss/src/uart_gnss.c @@ -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; -- 2.17.1