From cbaf893da4e34b4a128ee51d07d26eed01bfd187 Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Sun, 18 Jan 2026 18:34:45 +0800 Subject: [PATCH] =?utf8?q?=E4=BF=AE=E6=94=B9=E9=80=80=E5=87=BA=E5=93=84?= =?utf8?q?=E7=9D=A1=E4=BC=9A=E5=8D=A1=E6=AD=BB=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../thunderbird/src/ThunderBirdModel.cpp | 4 +- .../leiniao/imsl_ln/ln_api_story_random.c | 3 +- code/sdk/zhihui/utils/custom_spi.c | 161 ++++++++++++++++-- 3 files changed, 145 insertions(+), 23 deletions(-) diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp index e0660c3bc..1d0731cdf 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp @@ -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 { diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c index d42e059cc..8484f494f 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c @@ -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"); } diff --git a/code/sdk/zhihui/utils/custom_spi.c b/code/sdk/zhihui/utils/custom_spi.c index 50927bfd7..f3104f770 100644 --- a/code/sdk/zhihui/utils/custom_spi.c +++ b/code/sdk/zhihui/utils/custom_spi.c @@ -21,14 +21,20 @@ #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); -- 2.17.1