#include "lwip/apps/sntp.h"
#include <sys/time.h>
+#include <time.h>
#include "bletest.h"
#include "custom_utils.h"
#include "dev_authentication.h"
#include "bk_websocket.h"
+// 内存管理和错误处理优化
+#define AI_SAFE_MALLOC(size) ({ \
+ void* ptr = malloc(size); \
+ if (!ptr) { \
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Memory allocation failed: %s:%d", __FILE__, __LINE__); \
+ } \
+ ptr; \
+})
+
+#define AI_SAFE_FREE(ptr) do { \
+ if (ptr) { \
+ free(ptr); \
+ ptr = NULL; \
+ } \
+} while(0)
+
+// 超时和重试配置
+#define AI_CONNECT_TIMEOUT_MS 30000 // 30秒连接超时
+#define AI_RECEIVE_TIMEOUT_MS 60000 // 10秒接收超时
+#define AI_MAX_RETRY_COUNT 3 // 最大重试次数
+#define AI_QUEUE_CHECK_INTERVAL 1000 // 队列检查间隔(ms)
+
+// 资源保护
+static osMutexId_t g_ai_mutex = NULL;
+static uint32_t g_ai_memory_usage = 0;
+static uint32_t g_ai_max_memory = 1024 * 1024; // 1MB内存限制
+
+// 内存使用监控
+static inline bool ai_check_memory_limit(uint32_t size) {
+ if (g_ai_memory_usage + size > g_ai_max_memory) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Memory limit exceeded: %u + %u > %u",
+ g_ai_memory_usage, size, g_ai_max_memory);
+ return false;
+ }
+ return true;
+}
+
+static inline void ai_update_memory_usage(int32_t delta) {
+ if (delta > 0) {
+ g_ai_memory_usage += delta;
+ } else {
+ g_ai_memory_usage = (g_ai_memory_usage > (uint32_t)(-delta)) ?
+ g_ai_memory_usage + delta : 0;
+ }
+}
+// 线程安全保护
+#define AI_LOCK() do { \
+ if (g_ai_mutex) { \
+ osMutexAcquire(g_ai_mutex, osWaitForever); \
+ } \
+} while(0)
+
+#define AI_UNLOCK() do { \
+ if (g_ai_mutex) { \
+ osMutexRelease(g_ai_mutex); \
+ } \
+} while(0)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
+
#include "cmsis_os2.h"
#include "bk_websocket.h"
extern bool read_dev_token(char *data_token);
+errcode_t ai_system_init(void);
+void ai_cleanup_resources(void);
+uint32_t ai_get_memory_usage(void);
+uint32_t ai_get_memory_usage_percent(void);
+bool ai_check_queue_status(void);
+bool ai_system_health_check(void);
+
+// 外部函数声明
+// extern void bluetooth_get_local_addr(unsigned char *addr, int len);
+// extern void active_md5_buf(char *input, char *output);
+// extern void uapi_cat1_keep_wakeup(uint8_t state);
+// extern void set_AIStreamend(uint8_t state);
+// extern void set_clear_queue_stream(uint8_t state);
+// extern void startAudioCaptureTask(void);
+// extern void stop_AudioCaptureProcess_AI(void);
+// extern void ble_set_ai_Question_str(char *str);
+// extern void ble_set_ai_Answer_str(char *str, uint8_t type);
+// extern void SendMsgToUIService(uint32_t msg_id, uint32_t param, void *data, uint32_t len);
+// extern int send_msg_data_into_Ai_msg_queue(void *data, uint16_t len, uint16_t type);
+// extern bool aut_login(void);
+// extern bool get_dev_id(char *device_id);
+
static osTimerId_t g_timer_time_sync = NULL;
void uapi_start_tts_single_txt(char *buf);
}
void bk_websocket_demo(void *data) {
-
- // while (1)
+ uint32_t start_time = (uint32_t)osKernelGetTickCount();
+ uint32_t retry_count = 0;
+
+ // 初始化互斥锁
+ if (!g_ai_mutex) {
+ g_ai_mutex = osMutexNew(NULL);
+ if (!g_ai_mutex) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create AI mutex");
+ return;
+ }
+ }
+
+ AI_LOCK();
+ is_bk_websocket_chat = 1;
+ AI_UNLOCK();
+
+ char_reconnet:
{
- /* code */
- char_reconnet:
- is_bk_websocket_chat=1;
-
- char url_buf[248]={0};
- uint8_t is_raisound_url=0;
-
- if(chat_ws_url_init(url_buf,type_ai))
- {
- printf("%s\r\n",url_buf);
- is_raisound_url=1;
+ char url_buf[248] = {0};
+ uint8_t is_raisound_url = 0;
+ uint8_t client_count = AI_MAX_RETRY_COUNT;
+
+ // 检查内存使用情况
+ if (!ai_check_memory_limit(1024)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Memory limit exceeded, skipping connection");
+ goto cleanup_and_exit;
}
- else
- {
- is_raisound_url=0;
+
+ if (chat_ws_url_init(url_buf, type_ai)) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Chat URL: %s", url_buf);
+ is_raisound_url = 1;
+ } else {
+ is_raisound_url = 0;
}
- uint8_t client_count=3;
- while (client_count)
- {
- // http://118.145.158.207:22080ws://118.145.158.207:22080/chat/ws
- // ws://amp.raisound.com/chat/ws?dt=%s&platform=chinamobiledevice&bot_type=jiutian-lan
- // type_ai=AI_TYPE_DE;
- if(is_raisound_url)
- {
- chat_client = init_websocket_client(url_buf,NULL,1);
- }
- else
- {
+ // 连接重试循环
+ while (client_count > 0) {
+ uint32_t connect_start = (uint32_t)osKernelGetTickCount();
+
+ if (is_raisound_url) {
+ chat_client = init_websocket_client(url_buf, NULL, 1);
+ } else {
#ifdef SUPPORT_CHINA_MOBILE_AI_REGULATION
- chat_client = init_websocket_client(url_buf,NULL,0);
+ chat_client = init_websocket_client(url_buf, NULL, 0);
#else
- if(type_ai==AI_TYPE_JIU)
- {
- chat_client = init_websocket_client("ws://118.145.158.207:22080/chat/ws?&platform=chinamobiledevice&bot_type=jiutian-lan",NULL,0);
- }
- else if(type_ai==AI_TYPE_DOU)
- {
- chat_client = init_websocket_client("ws://118.145.158.207:22080/chat/ws?&platform=huoshan",NULL,0);
- }
- else if(type_ai==AI_TYPE_WEN)
- {
- chat_client = init_websocket_client("ws://118.145.158.207:22080/chat/ws?&platform=baidu",NULL,0);
- }
- else if(type_ai==AI_TYPE_KIMI)
- {
- chat_client = init_websocket_client("ws://118.145.158.207:22080/chat/ws?&platform=moonshot",NULL,0);
- }
- else if(type_ai==AI_TYPE_DE)
- {
- chat_client = init_websocket_client("ws://118.145.158.207:22080/chat/ws?platform=huoshan&model=ep-20250205103849-582m7",NULL,0);
- }
- else
- {
- chat_client = init_websocket_client("ws://118.145.158.207:22080/chat/ws?&platform=aliyun",NULL,0);
- }
+ const char* base_url = "ws://118.145.158.207:22080/chat/ws";
+ char full_url[512] = {0};
+
+ switch (type_ai) {
+ case AI_TYPE_JIU:
+ snprintf(full_url, sizeof(full_url), "%s?&platform=chinamobiledevice&bot_type=jiutian-lan", base_url);
+ break;
+ case AI_TYPE_DOU:
+ snprintf(full_url, sizeof(full_url), "%s?&platform=huoshan", base_url);
+ break;
+ case AI_TYPE_WEN:
+ snprintf(full_url, sizeof(full_url), "%s?&platform=baidu", base_url);
+ break;
+ case AI_TYPE_KIMI:
+ snprintf(full_url, sizeof(full_url), "%s?&platform=moonshot", base_url);
+ break;
+ case AI_TYPE_DE:
+ snprintf(full_url, sizeof(full_url), "%s?platform=huoshan&model=ep-20250205103849-582m7", base_url);
+ break;
+ default:
+ snprintf(full_url, sizeof(full_url), "%s?&platform=aliyun", base_url);
+ break;
+ }
+ chat_client = init_websocket_client(full_url, NULL, 0);
#endif
}
-
-
- if (chat_client== NULL) {
- client_count--;
- msleep(1000);
- continue ;
- }
- else
- {
+ if (chat_client == NULL) {
+ client_count--;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WebSocket connection failed, retries left: %d", client_count);
+
+ // 检查超时
+ if ((uint32_t)osKernelGetTickCount() - connect_start > AI_CONNECT_TIMEOUT_MS) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Connection timeout");
+ break;
+ }
+
+ msleep(1000);
+ continue;
+ } else {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket connection established");
break;
}
}
- if (chat_client== NULL){
- is_bk_websocket_chat=0;
- return;
- }
- server_state=0x02^server_state;
- if(server_state==0b00000111)
- {
- // uapi_start_asr();
- // uapi_start_tts_single_txt("2025英超夏季转会窗分阶段开启第一阶段2025年6月1日至2025年6月11日凌晨2:00北京时间第二阶段常规夏窗2025年6月16日至2025年9月2日凌晨2:00北京时间本贴将持续更新2025年夏窗以曼联转会相关为主的新闻和消息。");
+ if (chat_client == NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to establish WebSocket connection after %d retries", AI_MAX_RETRY_COUNT);
+ goto cleanup_and_exit;
}
-
- printf("chat_client succ");
- // send_ai_txt(1,"你是谁");
-
+
+ // 设置socket超时
+ struct timeval timeout;
+ timeout.tv_sec = AI_RECEIVE_TIMEOUT_MS / 1000;
+ timeout.tv_usec = (AI_RECEIVE_TIMEOUT_MS % 1000) * 1000;
+ lwip_setsockopt(chat_client->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+
+ server_state = 0x02 ^ server_state;
+
+ AI_LOCK();
set_ai_chat_service_init_flag(1);
+ AI_UNLOCK();
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Chat client initialized successfully");
+
WebSocketMessageType type;
- while (disconnect_server==0)
- {
- memset_s(recv_buf,1024,0,1024);
- int len= receive_websocket_message(chat_client,(unsigned char *)recv_buf,1024,&type);
- if(len==-1 || type == WS_CLOSE)
- {
- printf("disconnect_server chat_client");
+ uint32_t last_activity = (uint32_t)osKernelGetTickCount();
+
+ while (disconnect_server == 0) {
+ // 检查超时
+ if ((uint32_t)osKernelGetTickCount() - last_activity > AI_RECEIVE_TIMEOUT_MS) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Receive timeout, reconnecting...");
break;
}
- if(type==WS_PONG)
- {
- chat_client_ping=0;
+
+ memset_s(recv_buf, 1024, 0, 1024);
+ int len = receive_websocket_message(chat_client, (unsigned char *)recv_buf, 1024, &type);
+
+ if (len == -1 || type == WS_CLOSE) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WebSocket connection closed");
+ break;
}
- else
- {
- chat_result_analysis(recv_buf);
+
+ if (len > 0) {
+ last_activity = (uint32_t)osKernelGetTickCount();
+
+ if (type == WS_PONG) {
+ chat_client_ping = 0;
+ } else {
+ // 检查队列状态
+ AI_LOCK();
+ if (chat_reconnect == 1) {
+ AI_UNLOCK();
+ break;
+ }
+ AI_UNLOCK();
+
+ chat_result_analysis(recv_buf);
+ }
}
-
- if(chat_reconnect==1)
- {
- break;
+
+ // 定期检查资源状态
+ if (retry_count++ % 100 == 0) {
+ ai_update_memory_usage(0); // 更新内存使用统计
}
- printf("bk_websocket_demo %s",recv_buf);
+
+ msleep(10); // 避免过度占用CPU
}
+ AI_LOCK();
set_ai_chat_service_init_flag(0);
+ AI_UNLOCK();
+
lwip_close_websocket_client(chat_client);
- chat_client=NULL;
+ chat_client = NULL;
- if(chat_reconnect==1)
- {
- chat_reconnect=0;
+ if (chat_reconnect == 1) {
+ chat_reconnect = 0;
+ retry_count = 0;
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Reconnecting chat client...");
goto char_reconnet;
}
- is_bk_websocket_chat=0;
-
- chat_client_ping=0;
-
- // osThreadExit();
- printf("bk_websocket_demo end\r\n");
- return;
}
+
+cleanup_and_exit:
+ AI_LOCK();
+ is_bk_websocket_chat = 0;
+ chat_client_ping = 0;
+ AI_UNLOCK();
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Chat WebSocket demo ended");
+ return;
}
void bk_websocket_asr(void *data) {
-
- // while (1)
-
+ uint32_t start_time = (uint32_t)osKernelGetTickCount();
+ uint32_t retry_count = 0;
+
WebSocketMessageType type;
bool state = true;
- is_bk_websocket_asr=1;
- uint8_t is_raisound_url=0;
- // while (1)
+ AI_LOCK();
+ is_bk_websocket_asr = 1;
+ AI_UNLOCK();
+
+ uint8_t is_raisound_url = 0;
+
{
- char url_buf[124]={0};
- // if (g_test_server_index==0)
- {
- //ws://amp.raisound.com/asr/ws
- if(asr_ws_url_init(url_buf))
- {
- // printf("%s\r\n",url_buf);
- is_raisound_url=1;
- }
- else
- {
- // return;
- is_raisound_url=0;
- }
+ char url_buf[124] = {0};
+
+ if (asr_ws_url_init(url_buf)) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR URL: %s", url_buf);
+ is_raisound_url = 1;
+ } else {
+ is_raisound_url = 0;
}
+ uint8_t client_count = AI_MAX_RETRY_COUNT;
+
+ // 检查内存使用情况
+ if (!ai_check_memory_limit(0x400)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Memory limit exceeded for ASR buffer");
+ goto asr_cleanup_and_exit;
+ }
- uint8_t client_count=3;
-
- while (client_count && asr_need_stop==0)
- {
- if (g_test_server_index == 1)
- {
- asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws",NULL,0);
-
- }else if (g_test_server_index == 2)
- {
- asr_client = init_websocket_client("ws://110.42.224.129:8910/asr/ws",NULL,0);
-
- }else{
- if(is_raisound_url)
- asr_client = init_websocket_client(url_buf,NULL,1);
- else
- asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws",NULL,0);
-
+ while (client_count > 0 && asr_need_stop == 0) {
+ uint32_t connect_start = (uint32_t)osKernelGetTickCount();
+
+ if (g_test_server_index == 1) {
+ asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws", NULL, 0);
+ } else if (g_test_server_index == 2) {
+ asr_client = init_websocket_client("ws://110.42.224.129:8910/asr/ws", NULL, 0);
+ } else {
+ if (is_raisound_url) {
+ asr_client = init_websocket_client(url_buf, NULL, 1);
+ } else {
+ asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws", NULL, 0);
+ }
}
- if (asr_client== NULL) {
- printf("init_websocket_client fail %d\r\n",client_count);
+
+ if (asr_client == NULL) {
client_count--;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR WebSocket connection failed, retries left: %d", client_count);
+
+ // 检查超时
+ if ((uint32_t)osKernelGetTickCount() - connect_start > AI_CONNECT_TIMEOUT_MS) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR connection timeout");
+ break;
+ }
+
msleep(1000);
- continue ;
- }
- else
- {
+ continue;
+ } else {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR WebSocket connection established");
break;
}
}
- asr_need_stop=0;
-
- if (asr_client== NULL){
+ asr_need_stop = 0;
+ if (asr_client == NULL) {
bool state = false;
SendMsgToUIService(UI_AI_JUMP_TO_LISTENING_VIEW, 0, &state, sizeof(bool));
- is_bk_websocket_asr=0;
- return;
+ goto asr_cleanup_and_exit;
}
uapi_cat1_keep_wakeup(1);
- server_state=0x01^server_state;
- if(server_state==0b00000111)
- {
- // uapi_start_asr();
- // uapi_start_tts_single_txt("2025英超夏季转会窗分阶段开启第一阶段2025年6月1日至2025年6月11日凌晨2:00北京时间第二阶段常规夏窗2025年6月16日至2025年9月2日凌晨2:00北京时间本贴将持续更新2025年夏窗以曼联转会相关为主的新闻和消息。");
+ server_state = 0x01 ^ server_state;
+
+ // 安全分配ASR接收缓冲区
+ asr_recv_buf = (char *)AI_SAFE_MALLOC(0x400);
+ if (!asr_recv_buf) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to allocate ASR receive buffer");
+ goto asr_cleanup_and_exit;
}
-
- asr_recv_buf=(char *)malloc(0x400);
+ ai_update_memory_usage(0x400);
+
+ AI_LOCK();
set_ai_asr_service_init_flag(1);
+ AI_UNLOCK();
- if(osTimerIsRunning(g_timer_time_sync)==0 )
- {
- osStatus_t ret = osTimerStart(g_timer_time_sync,5000*3);
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE,"cat1 restart_time_sync timer ret %d\n",ret);
- }
-
- // uapi_start_asr();
- // SendMsgToUIService(UI_4G_AI_INIT_STAUS, 0,&state, sizeof(bool));
+ // if (osTimerIsRunning(g_timer_time_sync) == 0) {
+ // osStatus_t ret = osTimerStart(g_timer_time_sync, 5000 * 3);
+ // WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE, "cat1 restart_time_sync timer ret %d", ret);
+ // }
- int sndbuf_len = 1024*5;
+ // 设置socket缓冲区大小
+ int sndbuf_len = 1024 * 5;
lwip_setsockopt(asr_client->sockfd, SOL_SOCKET, SO_SNDBUF, &sndbuf_len, sizeof(sndbuf_len));
+
+ // 设置接收超时
+ struct timeval timeout;
+ timeout.tv_sec = AI_RECEIVE_TIMEOUT_MS / 1000;
+ timeout.tv_usec = (AI_RECEIVE_TIMEOUT_MS % 1000) * 1000;
+ lwip_setsockopt(asr_client->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
- uapi_start_asr();
+ uapi_start_asr();
- // asr_server_deinit();
+ uint32_t last_activity = (uint32_t)osKernelGetTickCount();
- while (disconnect_server==0)
- {
- memset_s(asr_recv_buf,1024,0,1024);
- int len= receive_websocket_message(asr_client,(unsigned char *)asr_recv_buf,1024,&type);
- // if(type==WS_CONT ||
- printf(" bk_websocket_asr type %d len %d\r\n",type,len);
- printf("bk_websocket_demo %s %d\n",asr_recv_buf,type);
+ while (disconnect_server == 0) {
+ // 检查超时
+ if ((uint32_t)osKernelGetTickCount() - last_activity > AI_RECEIVE_TIMEOUT_MS) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR receive timeout, reconnecting...");
+ break;
+ }
+
+ memset_s(asr_recv_buf, 1024, 0, 1024);
+ int len = receive_websocket_message(asr_client, (unsigned char *)asr_recv_buf, 1024, &type);
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR received: type=%d, len=%d", type, len);
- if( type==WS_CLOSE || len==-1)
- {
- printf("WS_lwip_close bk_websocket_asr\r\n");
+ if (type == WS_CLOSE || len == -1) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR WebSocket connection closed");
- if (len>2&& type==WS_CLOSE)
- {
- printf("WS_CLOSE reason %s\n",asr_recv_buf+2);
+ if (len > 2 && type == WS_CLOSE) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS_CLOSE reason: %s", asr_recv_buf + 2);
}
break;
}
- if(type==WS_TEXT)
- {
- if(false== aer_result_analysis(asr_recv_buf))
- {
- printf("WS_lwip_close false== aer_result_analysis(asr_recv_buf)\r\n");
- break;
+
+ if (len > 0) {
+ last_activity = (uint32_t)osKernelGetTickCount();
+
+ if (type == WS_TEXT) {
+ if (false == aer_result_analysis(asr_recv_buf)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR result analysis failed");
+ break;
+ }
+ } else if (type == WS_PONG) {
+ asr_client_ping = 0;
}
}
- if(type==WS_PONG)
- {
- asr_client_ping=0;
+
+ // 定期检查资源状态
+ if (retry_count++ % 100 == 0) {
+ ai_update_memory_usage(0);
}
- msleep(10);
+
+ msleep(10); // 避免过度占用CPU
}
+ AI_LOCK();
set_ai_asr_service_init_flag(0);
- free(asr_recv_buf);
+ AI_UNLOCK();
+
+ // 安全释放ASR接收缓冲区
+ AI_SAFE_FREE(asr_recv_buf);
+ ai_update_memory_usage(-0x400);
lwip_close_websocket_client(asr_client);
- asr_client=NULL;
+ asr_client = NULL;
- asr_client_ping=0;
+ asr_client_ping = 0;
msleep(1000);
- // return;
}
- is_bk_websocket_asr=0;
- return;
-
+asr_cleanup_and_exit:
+ AI_LOCK();
+ is_bk_websocket_asr = 0;
+ AI_UNLOCK();
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR WebSocket ended");
+ return;
}
void bk_websocket_tts(void *data) {
-
- // while (1)
- TTS_SATRT :
+ uint32_t start_time = (uint32_t)osKernelGetTickCount();
+ uint32_t retry_count = 0;
+
+ TTS_SATRT:
uapi_cat1_keep_wakeup(1);
WebSocketMessageType type;
bool state = true;
- is_bk_websocket_tts=1;
-
- uint8_t is_raisound_url=0;
+ AI_LOCK();
+ is_bk_websocket_tts = 1;
+ AI_UNLOCK();
+
+ uint8_t is_raisound_url = 0;
{
- // ws://amp.raisound.com/asr/ws
- char url_buf[124]={0};
- if(tts_ws_url_init(url_buf))
- {
- printf("%s\r\n",url_buf);
- is_raisound_url=1;
- }
- else
- {
- is_raisound_url=0;
+ char url_buf[124] = {0};
+ if (tts_ws_url_init(url_buf)) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS URL: %s", url_buf);
+ is_raisound_url = 1;
+ } else {
+ is_raisound_url = 0;
}
- uint8_t client_count=3;
-
-
+ uint8_t client_count = AI_MAX_RETRY_COUNT;
+
+ // 检查内存使用情况
+ if (!ai_check_memory_limit(1024 * 4)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Memory limit exceeded for TTS buffer");
+ goto tts_cleanup_and_exit;
+ }
- while (client_count)
- {
- if(is_raisound_url==1)
- {
- tts_client = init_websocket_client(url_buf,NULL,1);
- }
- else
- {
- tts_client = init_websocket_client("ws://118.145.158.207:22080/tts/stream?audio_buffer_size=1024",NULL,0);
+ while (client_count > 0) {
+ uint32_t connect_start = (uint32_t)osKernelGetTickCount();
+
+ if (is_raisound_url == 1) {
+ tts_client = init_websocket_client(url_buf, NULL, 1);
+ } else {
+ tts_client = init_websocket_client("ws://118.145.158.207:22080/tts/stream?audio_buffer_size=1024", NULL, 0);
}
-
- if (tts_client== NULL)
- {
- printf("init_websocket_client fail %d\r\n",client_count);
+ if (tts_client == NULL) {
client_count--;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TTS WebSocket connection failed, retries left: %d", client_count);
+
+ // 检查超时
+ if ((uint32_t)osKernelGetTickCount() - connect_start > AI_CONNECT_TIMEOUT_MS) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TTS connection timeout");
+ break;
+ }
+
msleep(1000);
- continue ;
- }
- else
- {
- printf("tts_client init_websocket_client succ \r\n");
+ continue;
+ } else {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS WebSocket connection established");
break;
}
}
- if (tts_client== NULL){
- is_bk_websocket_tts=0;
- return;
- }
-
- server_state=0x04^server_state;
- if(server_state==0b00000111)
- {
- // uapi_start_asr();
- // uapi_start_tts_single_txt("2025英超夏季转会窗分阶段开启第一阶段2025年6月1日至2025年6月11日凌晨2:00北京时间第二阶段常规夏窗2025年6月16日至2025年9月2日凌晨2:00北京时间本贴将持续更新2025年夏窗以曼联转会相关为主的新闻和消息。");
+
+ if (tts_client == NULL) {
+ goto tts_cleanup_and_exit;
}
- tts_break=0;
+ server_state = 0x04 ^ server_state;
-// uapi_start_tts_single();
-
- char* tts_recv_buf=(char *)malloc(1024*4);
+ tts_break = 0;
+
+ // 安全分配TTS接收缓冲区
+ char* tts_recv_buf = (char *)AI_SAFE_MALLOC(1024 * 4);
+ if (!tts_recv_buf) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to allocate TTS receive buffer");
+ goto tts_cleanup_and_exit;
+ }
+ ai_update_memory_usage(1024 * 4);
+ AI_LOCK();
set_ai_tts_server_init_flag(1);
+ AI_UNLOCK();
+
+ // 设置socket超时
+ struct timeval timeout;
+ timeout.tv_sec = AI_RECEIVE_TIMEOUT_MS / 1000;
+ timeout.tv_usec = (AI_RECEIVE_TIMEOUT_MS % 1000) * 1000;
+ lwip_setsockopt(tts_client->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
- while (disconnect_server==0)
- {
+ uint32_t last_activity = (uint32_t)osKernelGetTickCount();
+
+ while (disconnect_server == 0) {
+ // 检查超时
+ if ((uint32_t)osKernelGetTickCount() - last_activity > AI_RECEIVE_TIMEOUT_MS) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TTS receive timeout, reconnecting...");
+ break;
+ }
+ memset_s(tts_recv_buf, 1024 * 4, 0, 1024 * 4);
+ int len = receive_websocket_message(tts_client, (unsigned char *)tts_recv_buf, 1024 * 4, &type);
- memset_s(tts_recv_buf,1024*4,0,1024*4);
- int len=receive_websocket_message(tts_client,(unsigned char *)tts_recv_buf,1024*4,&type);
- // if(type==WS_CONT ||
- if( type==WS_CLOSE || len==-1 || tts_reconnect==1)//|| type==WS_CONT )
- {
- printf("WS_lwip_close bk_websocket_tts\r\n");
+ if (type == WS_CLOSE || len == -1 || tts_reconnect == 1) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TTS WebSocket connection closed");
break;
}
- // printf("bk_websocket_tts bk_websocket_tts %d\r\n",type);
- if(type==WS_BINARY)
- {
- if(bk_websocket_tts_tick==0)
- {
- set_AIStreamend(0);
- bk_websocket_tts_tick = (uint32_t)osKernelGetTickCount();
- }
- // tts_cache_file((uint8_t *)tts_recv_buf,len);——
- // AIStreamWrite((uint8_t *)tts_recv_buf,len);
- send_msg_data_into_Ai_msg_queue((uint8_t *)tts_recv_buf,len,200);
- printf("bk_websocket_demo tts %d\n",len);
- //
- msleep(1);
+
+ if (len > 0) {
+ last_activity = (uint32_t)osKernelGetTickCount();
+ if (type == WS_BINARY) {
+ if (bk_websocket_tts_tick == 0) {
+ set_AIStreamend(0);
+ bk_websocket_tts_tick = (uint32_t)osKernelGetTickCount();
+ }
+ send_msg_data_into_Ai_msg_queue((uint8_t *)tts_recv_buf, len, 200);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS binary data received: %d bytes", len);
+ msleep(1);
+ } else if (type == WS_TEXT) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS text data received: %s", tts_recv_buf);
+ send_msg_data_into_Ai_msg_queue((uint8_t *)tts_recv_buf, len, 201);
+ bk_websocket_tts_tick = 0;
+ } else if (type == WS_PONG) {
+ tts_client_ping = 0;
+ }
}
- else if(type==WS_TEXT)
- {
- printf("bk_websocket_demo %s %d %d\n",tts_recv_buf,bk_websocket_tts_tick,(uint32_t)osKernelGetTickCount());
-
- send_msg_data_into_Ai_msg_queue((uint8_t *)tts_recv_buf,len,201);
- bk_websocket_tts_tick=0;
- // tts_paly();
- }
- if(type==WS_PONG)
- {
- tts_client_ping=0;
+
+ // 定期检查资源状态
+ if (retry_count++ % 100 == 0) {
+ ai_update_memory_usage(0);
}
- // aer_result_analysis(asr_recv_buf);
+
+ msleep(1); // 避免过度占用CPU
}
- bk_websocket_tts_tick=0;
+ bk_websocket_tts_tick = 0;
+ AI_LOCK();
set_ai_tts_server_init_flag(0);
+ AI_UNLOCK();
- free(tts_recv_buf);
+ // 安全释放TTS接收缓冲区
+ AI_SAFE_FREE(tts_recv_buf);
+ ai_update_memory_usage(-1024 * 4);
lwip_close_websocket_client(tts_client);
- tts_client=NULL;
+ tts_client = NULL;
- if(tts_reconnect)
- {
- if(disconnect_server==0)
- {
+ if (tts_reconnect) {
+ if (disconnect_server == 0) {
set_clear_queue_stream(1);
- goto TTS_SATRT;
+ retry_count = 0;
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Reconnecting TTS client...");
+
}
- tts_reconnect=0;
+ tts_reconnect = 0;
+ goto TTS_SATRT;
}
-
}
- is_bk_websocket_tts=0;
- tts_client_ping=0;
+
+tts_cleanup_and_exit:
+ AI_LOCK();
+ is_bk_websocket_tts = 0;
+ tts_client_ping = 0;
+ AI_UNLOCK();
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS WebSocket ended");
return;
-
}
app_task_definition_t tts_taskcfg={0};
void asr_server_deinit(void)
{
-
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"asr_server_deinit");
+
if(send_websocket_message(asr_client,(uint8_t *)"WS_CLOSE",strlen("WS_CLOSE"),WS_CLOSE))
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"WS_CLOSE");
void chat_server_deinit(void)
{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"chat_server_deinit");
if(send_websocket_message(chat_client,(uint8_t *)"WS_CLOSE",strlen("WS_CLOSE"),WS_CLOSE))
{
void tts_server_deinit(void)
{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"tts_server_deinit");
if(send_websocket_message(tts_client,(uint8_t *)"WS_CLOSE",strlen("WS_CLOSE"),WS_CLOSE))
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"WS_CLOSE");
bool init_ai_task(uint8_t type)
{
- if(is_init_ai)
- {
- disconnect_server=0;
+ if (is_init_ai) {
+ // 初始化AI系统
+ if (ai_system_init() != ERRCODE_SUCC) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to initialize AI system");
+ return false;
+ }
+
+ // 系统健康检查
+ if (!ai_system_health_check()) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AI system health check failed");
+ return false;
+ }
+
+ disconnect_server = 0;
g_timer_time_sync = osTimerNew((osTimerFunc_t)time_sync_func, osTimerPeriodic, NULL, NULL);
- if (g_timer_time_sync == NULL)
- {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"g_timer_time_sync create failed\n");
+ if (g_timer_time_sync == NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "g_timer_time_sync create failed");
+ ai_cleanup_resources();
+ return false;
+ }
+
+ type_ai = type;
+
+ // 初始化TTS播放
+ if (uapi_tts_paly_init() != ERRCODE_SUCC) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to initialize TTS playback");
+ ai_cleanup_resources();
+ return false;
}
- type_ai=type;
- uapi_tts_paly_init();
- tts_server_init();
- chat_server_init();
+ // 初始化TTS服务器
+ if (tts_server_init() != ERRCODE_SUCC) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to initialize TTS server");
+ ai_cleanup_resources();
+ return false;
+ }
+
+ // 初始化聊天服务器
+ if (chat_server_init() != ERRCODE_SUCC) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to initialize chat server");
+ ai_cleanup_resources();
+ return false;
+ }
- // voice_chat_server_init();
- // is_init_ai=0;
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AI task initialized successfully, type: %d", type);
}
return true;
bool dinit_ai_task(void)
{
- if(is_init_ai)
- {
- disconnect_server=1;
+ if (is_init_ai) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Deinitializing AI task...");
+
+ disconnect_server = 1;
- if(g_timer_time_sync)
- {
+ if (g_timer_time_sync) {
osTimerDelete(g_timer_time_sync);
- g_timer_time_sync =NULL;
+ g_timer_time_sync = NULL;
}
- uapi_tts_paly_stop();
+ // 停止TTS播放
+ if (uapi_tts_paly_stop() != ERRCODE_SUCC) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to stop TTS playback");
+ }
+ // 清理服务器连接
asr_server_deinit();
-
chat_server_deinit();
-
tts_server_deinit();
- // is_init_ai=0;
+
+ // 清理AI系统资源
+ ai_cleanup_resources();
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AI task deinitialized successfully");
}
return true;
bool start_ai_voice_chat()
{
unsigned char deviceId[20] = {0};
- memset(deviceId,0,6);
+ memset(deviceId, 0, 6);
- bluetooth_get_local_addr(&deviceId[0],6);
+ bluetooth_get_local_addr(&deviceId[0], 6);
char deviceId_temp[20] = {0};
- sprintf(deviceId_temp,"%02X%02x%02X%02x%02X%02x",deviceId[5],deviceId[4],deviceId[3],deviceId[2],deviceId[1],deviceId[0]);
-
+ sprintf(deviceId_temp, "%02X%02x%02X%02x%02X%02x", deviceId[5], deviceId[4], deviceId[3], deviceId[2], deviceId[1], deviceId[0]);
time_t timestamp;
timestamp = time(NULL);
- long long timestamp_ms = (long long)timestamp ;
+ long long timestamp_ms = (long long)timestamp;
- char* timestamp_str_2=(char *)malloc(20);
- memset(timestamp_str_2,0,20);
+ char* timestamp_str_2 = (char *)AI_SAFE_MALLOC(20);
+ if (!timestamp_str_2) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to allocate timestamp buffer");
+ return false;
+ }
+ ai_update_memory_usage(20);
+
+ memset(timestamp_str_2, 0, 20);
sprintf(timestamp_str_2, "%lld", timestamp_ms);
- char md5_buf[33]={0};
- active_md5_buf((char *)timestamp_str_2,md5_buf);
- printf("md5_buf:%s",md5_buf);
+ char md5_buf[33] = {0};
+ active_md5_buf((char *)timestamp_str_2, md5_buf);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "MD5 buffer: %s", md5_buf);
// 释放timestamp_str_2内存
- free(timestamp_str_2);
+ AI_SAFE_FREE(timestamp_str_2);
+ ai_update_memory_usage(-20);
- char jsonString[800]={0};
- sprintf(jsonString, "{ \
+ char jsonString[800] = {0};
+ sprintf(jsonString, "{ \
\"header\": { \
\"trace_id\": \"%s\", \
\"event\":\"Start\" \
\"voice\": \"zh_female_shuangkuaisisi_moon_bigtts\", \
\"voice_detection\": \"disable\" \
} \
- } ",md5_buf,deviceId_temp)
- ;
+ } ", md5_buf, deviceId_temp);
- if (send_websocket_message(voice_chat_client,( uint8_t *)jsonString,strlen(jsonString),WS_TEXT)==0)
- {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ %s\n",jsonString);
- return true;
- }
-
- else
- {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message erro\n");
- return false;
+ if (send_websocket_message(voice_chat_client, (uint8_t *)jsonString, strlen(jsonString), WS_TEXT) == 0) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Voice chat start message sent successfully: %s", jsonString);
+ return true;
+ } else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to send voice chat start message");
+ return false;
}
-
}
}
void voice_chat_websocket(void *data) {
-
- // while (1)
+ uint32_t start_time = (uint32_t)osKernelGetTickCount();
+ uint32_t retry_count = 0;
+
uapi_cat1_keep_wakeup(1);
WebSocketMessageType type;
bool state = true;
- is_bk_websocket_tts=1;
-
- uint8_t is_raisound_url=0;
+ AI_LOCK();
+ is_bk_websocket_tts = 1;
+ AI_UNLOCK();
+
+ uint8_t is_raisound_url = 0;
{
- // ws://amp.raisound.com/asr/ws
- char url_buf[124]={0};
- // if(tts_ws_url_init(url_buf))
- // {
- // printf("%s\r\n",url_buf);
- // is_raisound_url=1;
- // }
- // else
- // {
- // is_raisound_url=0;
- // }
-
- uint8_t client_count=3;
-
-
+ char url_buf[124] = {0};
+
+ uint8_t client_count = AI_MAX_RETRY_COUNT;
+
+ // 检查内存使用情况
+ if (!ai_check_memory_limit(1024 * 4)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Memory limit exceeded for voice chat buffer");
+ goto voice_chat_cleanup_and_exit;
+ }
- while (client_count)
- {
- if(is_raisound_url==1)
- {
- voice_chat_client = init_websocket_client(url_buf,NULL,1);
- }
- else
- {
- // http://118.145.158.207:22080ws://118.145.158.207:22080/voice-chat/ws
- // /voice-chat/v2/ws
- voice_chat_client = init_websocket_client("ws://118.145.158.207:22080/voice-chat/v2/ws?platform=huoshan",NULL,0);
+ while (client_count > 0) {
+ uint32_t connect_start = (uint32_t)osKernelGetTickCount();
+
+ if (is_raisound_url == 1) {
+ voice_chat_client = init_websocket_client(url_buf, NULL, 1);
+ } else {
+ voice_chat_client = init_websocket_client("ws://118.145.158.207:22080/voice-chat/v2/ws?platform=huoshan", NULL, 0);
}
-
- if (voice_chat_client== NULL)
- {
- printf("init_websocket_client fail %d\r\n",client_count);
+ if (voice_chat_client == NULL) {
client_count--;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Voice chat WebSocket connection failed, retries left: %d", client_count);
+
+ // 检查超时
+ if ((uint32_t)osKernelGetTickCount() - connect_start > AI_CONNECT_TIMEOUT_MS) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Voice chat connection timeout");
+ break;
+ }
+
msleep(1000);
- continue ;
- }
- else
- {
- printf("tts_client init_websocket_client succ \r\n");
+ continue;
+ } else {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Voice chat WebSocket connection established");
break;
}
}
- if (voice_chat_client== NULL){
- is_bk_websocket_tts=0;
- return;
+
+ if (voice_chat_client == NULL) {
+ goto voice_chat_cleanup_and_exit;
+ }
+
+ // 安全分配voice chat接收缓冲区
+ char* voice_chat_client_buf = (char *)AI_SAFE_MALLOC(1024 * 4);
+ if (!voice_chat_client_buf) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to allocate voice chat receive buffer");
+ goto voice_chat_cleanup_and_exit;
+ }
+ ai_update_memory_usage(1024 * 4);
+
+ // 设置socket超时
+ struct timeval timeout;
+ timeout.tv_sec = AI_RECEIVE_TIMEOUT_MS / 1000;
+ timeout.tv_usec = (AI_RECEIVE_TIMEOUT_MS % 1000) * 1000;
+ lwip_setsockopt(voice_chat_client->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+
+ if (!start_ai_voice_chat()) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to start AI voice chat");
+ AI_SAFE_FREE(voice_chat_client_buf);
+ ai_update_memory_usage(-1024 * 4);
+ goto voice_chat_cleanup_and_exit;
}
-
- char* voice_chat_client_buf=(char *)malloc(1024*4);
-
- start_ai_voice_chat();
-
- while (disconnect_server==0)
- {
+ uint32_t last_activity = (uint32_t)osKernelGetTickCount();
+
+ while (disconnect_server == 0) {
+ // 检查超时
+ if ((uint32_t)osKernelGetTickCount() - last_activity > AI_RECEIVE_TIMEOUT_MS) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Voice chat receive timeout, reconnecting...");
+ break;
+ }
+ memset_s(voice_chat_client_buf, 1024 * 4, 0, 1024 * 4);
+ int len = receive_websocket_message(voice_chat_client, (unsigned char *)voice_chat_client_buf, 1024 * 4, &type);
- memset_s(voice_chat_client_buf,1024*4,0,1024*4);
- int len=receive_websocket_message(voice_chat_client,(unsigned char *)voice_chat_client_buf,1024*4,&type);
- // if(type==WS_CONT ||
- if( type==WS_CLOSE || len==-1)//|| type==WS_CONT )
- {
- printf("WS_lwip_close bk_websocket_tts\r\n");
+ if (type == WS_CLOSE || len == -1) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Voice chat WebSocket connection closed");
break;
}
- // printf("bk_websocket_tts bk_websocket_tts %d\r\n",type);
- if(type==WS_BINARY)
- {
- if(bk_websocket_tts_tick==0)
- {
- set_AIStreamend(0);
- bk_websocket_tts_tick = (uint32_t)osKernelGetTickCount();
- }
- send_msg_data_into_Ai_msg_queue((uint8_t *)voice_chat_client_buf,len,200);
- printf("receive_websocket_message voice_chat %d\n",len);
- msleep(1);
+
+ if (len > 0) {
+ last_activity = (uint32_t)osKernelGetTickCount();
+ if (type == WS_BINARY) {
+ if (bk_websocket_tts_tick == 0) {
+ set_AIStreamend(0);
+ bk_websocket_tts_tick = (uint32_t)osKernelGetTickCount();
+ }
+ send_msg_data_into_Ai_msg_queue((uint8_t *)voice_chat_client_buf, len, 200);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Voice chat binary data received: %d bytes", len);
+ msleep(1);
+ } else if (type == WS_TEXT) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Voice chat text data received: %s", voice_chat_client_buf);
+ voice_chat_analysis(voice_chat_client_buf);
+ }
}
- else if(type==WS_TEXT)
- {
- printf("receive_websocket_message voice_chat %s\n",voice_chat_client_buf);
- voice_chat_analysis(voice_chat_client_buf);
- // tts_paly();
+
+ // 定期检查资源状态
+ if (retry_count++ % 100 == 0) {
+ ai_update_memory_usage(0);
}
- // aer_result_analysis(asr_recv_buf);
+
+ msleep(1); // 避免过度占用CPU
}
- bk_websocket_tts_tick=0;
+ bk_websocket_tts_tick = 0;
lwip_close_websocket_client(voice_chat_client);
- voice_chat_client=NULL;
+ voice_chat_client = NULL;
// 释放voice_chat_client_buf内存
- free(voice_chat_client_buf);
-
- // return;
+ AI_SAFE_FREE(voice_chat_client_buf);
+ ai_update_memory_usage(-1024 * 4);
}
- is_bk_websocket_tts=0;
-
+
+voice_chat_cleanup_and_exit:
+ AI_LOCK();
+ is_bk_websocket_tts = 0;
+ AI_UNLOCK();
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Voice chat WebSocket ended");
+ return;
}
+
+
+// 资源清理函数
+void ai_cleanup_resources(void) {
+ AI_LOCK();
+
+ // 清理互斥锁
+ if (g_ai_mutex) {
+ osMutexDelete(g_ai_mutex);
+ g_ai_mutex = NULL;
+ }
+
+ // 清理定时器
+ if (g_timer_time_sync) {
+ osTimerDelete(g_timer_time_sync);
+ g_timer_time_sync = NULL;
+ }
+
+ // 重置内存使用统计
+ g_ai_memory_usage = 0;
+
+ AI_UNLOCK();
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AI resources cleaned up");
+}
+
+// 初始化AI系统
+errcode_t ai_system_init(void) {
+ // 创建互斥锁
+ g_ai_mutex = osMutexNew(NULL);
+ if (!g_ai_mutex) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create AI mutex");
+ return ERRCODE_FAIL;
+ }
+
+ // 初始化内存使用统计
+ g_ai_memory_usage = 0;
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AI system initialized successfully");
+ return ERRCODE_SUCC;
+}
+
+// 获取内存使用情况
+uint32_t ai_get_memory_usage(void) {
+ return g_ai_memory_usage;
+}
+
+// 获取内存使用百分比
+uint32_t ai_get_memory_usage_percent(void) {
+ return (g_ai_memory_usage * 100) / g_ai_max_memory;
+}
+
+// 队列状态检查函数
+bool ai_check_queue_status(void) {
+ // 这里可以添加队列状态检查逻辑
+ // 例如检查消息队列是否已满
+ return true;
+}
+
+// 系统健康检查
+bool ai_system_health_check(void) {
+ uint32_t memory_usage = ai_get_memory_usage_percent();
+
+ if (memory_usage > 90) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Memory usage too high: %u%%", memory_usage);
+ return false;
+ }
+
+ if (!ai_check_queue_status()) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Queue status check failed");
+ return false;
+ }
+
+ return true;
+}
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
\ No newline at end of file