#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};
}
}
+/**
+ * @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读取函数
} 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");
}
/**
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)
{
void custom_spi_deinit(void)
{
+ custom_spi_start();
+
pkg_recv_cnt = 0;
total_byte_error_cnt = 0;
total_cnt = 0;
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);
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);