修改退出哄睡会卡死的bug 3105/1 3105/head 3106/target/1
authorxue <2144439972@qq.com>
Sun, 18 Jan 2026 10:34:45 +0000 (18:34 +0800)
committerxue <2144439972@qq.com>
Sun, 18 Jan 2026 10:34:45 +0000 (18:34 +0800)
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp
code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c
code/sdk/zhihui/utils/custom_spi.c

index e0660c3..1d0731c 100644 (file)
@@ -3106,13 +3106,11 @@ extern "C" {
             // 发送中断消息(通知服务器停止发送音频数据)
             ln_ws_send_voice_chat_interrupt("退出哄睡");
             // 等待一小段时间,确保WebSocket线程处理完中断消息
-            LOS_Msleep(100);
             //推送结束故事消息
-            do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_STORY_FINISH, NULL, 0);
+             ln_ws_send_sleep_mode_end_ack(true, "哄睡模式结束");
             // 音频deinit(清理音频资源)
             do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_AUDIO_DEINIT, NULL, 0);
             // 等待音频deinit完成,避免在音频清理过程中切换视图
-            LOS_Msleep(50);
             // 切换视图
             ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_STATUS_SHOW);
         } else {
index d42e059..8484f49 100644 (file)
@@ -406,11 +406,10 @@ void ln_parse_sleep_mode_end(const char *json_str, int json_len)
        (void)json_len;
        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN][SLEEP_END] received\n");
        /* 标记故事结束,供UI状态机使用 */
-    ln_voice_chat_interrupt("哄睡模式结束");
+    // ln_voice_chat_interrupt("哄睡模式结束");
     push_sleep_mode_end_notification();
     // 标记为结束哄睡(在通知之后清除,作为保护机制)
     uapi_set_sleep_mode_active(false);
-    ln_ws_send_sleep_mode_end_ack(true, "哄睡模式结束");
     
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN][SLEEP_END] sleep mode flag cleared\n");
 }
index 50927bf..f3104f7 100644 (file)
 #include "custom_spi.h"
 #include "custom_utils.h"
 #include "pm.h"
+#include "cmsis_os2.h"
 
 void custom_spi_start(void);
 
-/* Python服务版本号获取函数 - 使用 cat1_pub_api.h 中的声明 */
-#include "cat1_pub_api.h"
+/* 外部变量:Python服务版本号 */
+#ifdef SUPPORT_CAT1_SERVICE
+extern uint8_t g_py_ver;
+#else
+uint8_t g_py_ver = 28;
+#endif
 
 static osSemaphoreId_t g_semaphore_spi_id = NULL;
 static app_task_definition_t taskcfg={0};
+static volatile int g_custom_spi_running = 0;  // SPI任务运行标志
 static uint32_t total_cnt = 0;
 static uint8_t g_rx_buffer[1024] = {0};
 
@@ -423,14 +429,63 @@ void custom_spi_read(void)
     }
 }
 
+/**
+ * @brief 验证线程名和ID是否匹配,避免ID被复用
+ * @param threadId 线程ID
+ * @param expectedName 期望的线程名称
+ * @return true表示匹配,false表示不匹配或线程无效
+ */
+static bool IsValidThread(osThreadId_t threadId, const char* expectedName)
+{
+    if (threadId == NULL || expectedName == NULL) {
+        return false;
+    }
+    
+    // 首先检查线程状态,如果线程已经不存在,直接返回false
+    osThreadState_t threadState = osThreadGetState(threadId);
+    if (threadState == osThreadError) {
+        return false;  // 线程不存在或无效
+    }
+    
+    // 获取线程名称
+    const char* actualName = osThreadGetName(threadId);
+    if (actualName == NULL) {
+        return false;
+    }
+    
+    // 比较线程名称
+    bool nameMatch = (strcmp(actualName, expectedName) == 0);
+    
+    return nameMatch;
+}
+
+volatile uint8_t custom_spi_service_task_is_stop=0;
+
 void custom_spi_service_task(void *arg)
 {
     printf("SPI处理任务启动,开始等待中断...\r\n");
+
+    custom_spi_service_task_is_stop=0;
     
-    // 任务循环:永久运行,处理每次中断
-    while (1) {
+    // 任务循环:使用运行标志控制,处理每次中断
+    while (g_custom_spi_running) {
         // 3. 等待信号量(阻塞,直到中断释放/超时)
-        errcode_t ret = osSemaphoreAcquire(g_semaphore_spi_id, 60 * 1000);
+        errcode_t ret=0;
+        if(g_semaphore_spi_id!=NULL && g_custom_spi_running)
+        {
+            ret= osSemaphoreAcquire(g_semaphore_spi_id, 60 * 1000);
+        }
+        else
+        {
+            printf("semaphore not found, custom_spi_service_task_is_stop: %d\r\n",custom_spi_service_task_is_stop);
+            break;
+        }
+         
+        if(g_custom_spi_running == 0)
+        {
+            printf("g_custom_spi_running is 0, custom_spi_service_task_is_stop: %d\r\n",custom_spi_service_task_is_stop);
+            break;
+        }
         
         if (ret == 0) {
             // 4. 信号量获取成功:根据版本调用对应的SPI读取函数
@@ -449,12 +504,26 @@ void custom_spi_service_task(void *arg)
         } else if (ret == osErrorTimeout) {
             // 超时处理:打印日志,继续循环等待
             printf("SPI中断等待超时%d秒,继续等待...\r\n", 60);
+            
         } else {
             // 信号量错误:退出循环,任务结束(可选重试逻辑)
             printf("信号量获取失败 状态:%d,任务退出\r\n", ret);
-            // break;
+            printf("g_custom_spi_running is 0, custom_spi_service_task_is_stop: %d\r\n",custom_spi_service_task_is_stop);
+            break;
         }
     }
+
+    printf("custom_spi_service_task end ...\r\n");
+
+    if (g_semaphore_spi_id != NULL ) 
+    {
+        osSemaphoreDelete(g_semaphore_spi_id);
+        g_semaphore_spi_id = NULL;
+    }
+
+    custom_spi_service_task_is_stop=1;
+
+    printf("custom_spi_service_task end \r\n");
 }
 
 /**
@@ -591,13 +660,16 @@ void custom_spi_init(void)
     taskcfg.func = custom_spi_service_task;
     taskcfg.use_mem = USE_EXTEND_MEM;
     
+    // 设置运行标志,在创建线程之前设置,确保线程不会立即退出
+    g_custom_spi_running = 1;
+    
     ret=uapi_create_osThread_custom(&taskcfg);
     if(ret != ERRCODE_SUCC)
     {
         printf("create custom_spi_service_task failed %d!\r\n",ret);
+        g_custom_spi_running = 0;  // 创建失败,重置标志
         goto FAILED;
     }
-
     uint8_t cnt = pm_veto_get_id_cnt(PM_ID_SPI);
     if (cnt == 0) 
     {
@@ -626,6 +698,8 @@ FAILED:
 
 void custom_spi_deinit(void)
 {
+    custom_spi_start();
+
     pkg_recv_cnt = 0;
     total_byte_error_cnt = 0;
     total_cnt = 0;
@@ -635,15 +709,70 @@ void custom_spi_deinit(void)
     g_last_logged_packet_seq = 0;  // 重置日志记录序号
     errcode_t ret = 0;
 
-    if(taskcfg.task_handle)
-    {
-        ret = uapi_terminate_thread(taskcfg.task_handle);
-        if (ret != ERRCODE_SUCC) {
-            printf("uapi_terminate_thread failed: 0x%x\n", ret);
+    // 设置运行标志为0,让线程自然退出
+
+  
+    // 等待线程退出
+    if (taskcfg.task_handle != NULL) {
+
+        g_custom_spi_running = 0;
+
+        if (g_semaphore_spi_id != NULL) {
+        osSemaphoreRelease(g_semaphore_spi_id);
+        // printf("SPI中断触发,释放信号量\r\n");
+        }
+        osThreadId_t threadId = (osThreadId_t)taskcfg.task_handle;
+        const char* threadName = "custom_spi_service";
+        
+        // 验证线程ID和名称是否匹配,避免ID被复用
+        if (!IsValidThread(threadId, threadName)) {
+            printf("Thread ID may have been reused, thread name mismatch. Expected: %s\r\n", threadName);
+            printf("Assuming thread already stopped due to ID reuse\r\n");
+        } else {
+            printf("Thread validation passed, waiting for thread: %s\r\n", threadName);
+            
+            // 首先尝试使用 osThreadJoin 等待线程结束
+            osStatus_t joinStatus = osThreadJoin(threadId);
+            if (joinStatus == osOK) {
+                printf("Custom SPI thread stopped successfully (osThreadJoin)\r\n");
+            } else {
+                // 如果 osThreadJoin 不可用或失败,使用状态检查
+                printf("osThreadJoin failed (%d), using state check...\r\n", joinStatus);
+                
+                // 使用 osThreadGetState 检查线程状态
+                for (int i = 0; i < 50; i++) {
+                    usleep(100000); // 100ms
+                    
+                    // 再次验证线程,防止在等待过程中ID被复用
+                    if (!IsValidThread(threadId, threadName) && custom_spi_service_task_is_stop) {
+                        printf("Thread ID reused during wait, stopping check %d\r\n",custom_spi_service_task_is_stop);
+                        usleep(100000); // 100ms
+                        break;
+                    }
+                    
+                    osThreadState_t threadState = osThreadGetState(threadId);
+                    
+                    // 检查线程状态,如果线程不存在或已终止,则认为已停止
+                    bool thread_running = (threadState == osThreadReady || 
+                                         threadState == osThreadRunning || 
+                                         threadState == osThreadBlocked);
+                    
+                    printf("Waiting... %d/50 (state: %d, running: %s)\r\n", 
+                           i + 1, threadState, thread_running ? "yes" : "no");
+                    
+                    if (!thread_running && custom_spi_service_task_is_stop) {
+                        printf("Custom SPI thread stopped successfully (state check) %d\r\n",custom_spi_service_task_is_stop);
+                        usleep(100000); // 100ms
+                        break;
+                    }
+                }
+            }
         }
+        
         taskcfg.task_handle = NULL;
+    } else {
+        printf("No valid thread handle, assuming thread already stopped\r\n");
     }
-
     
     uapi_pin_set_ie(S_MGPIO23,HAL_PIO_IE_DISABLE);
 
@@ -657,11 +786,7 @@ void custom_spi_deinit(void)
         printf("uapi_spi_deinit failed: 0x%x\n", ret);
     }
 
-    if (g_semaphore_spi_id != NULL) 
-    {
-        osSemaphoreDelete(g_semaphore_spi_id);
-        g_semaphore_spi_id = NULL;
-    }
+  
 
     uapi_pm_request_mode(PM_ID_SPI, PM_MODE_NORMAL);