Преглед изворни кода

fix: airlink, airlink_pause_mutex再改善一下

??? пре 2 месеци
родитељ
комит
416a39cc9c

+ 35 - 9
components/airlink/src/luat_airlink.c

@@ -57,6 +57,8 @@ int luat_airlink_start(int id)
     {
         luat_rtos_queue_create(&airlink_ippkg_queue, AIRLINK_QUEUE_SIZE, sizeof(airlink_queue_item_t));
     }
+    // 初始化 pause 信号量,持久化创建一次,初始为空用于阻塞等待
+    luat_airlink_pause_init();
     if (id == 0)
     {
         #ifdef LUAT_USE_AIRLINK_SPI_SLAVE
@@ -90,25 +92,49 @@ int luat_airlink_start(int id)
     return 0;
 }
 
-void luat_airlink_pause_init(void) {
+void luat_airlink_pause_init(void)
+{
     if (g_airlink_pause_mutex == NULL)
     {
-        g_airlink_pause_mutex = luat_rtos_mutex_create(&g_airlink_pause_mutex);
+        if (luat_rtos_mutex_create(&g_airlink_pause_mutex) != 0)
+        {
+            LLOGW("airlink create pause mutex failed");
+        }
     }
 }
 
-void luat_airlink_set_pause(uint32_t val) {
+void luat_airlink_set_pause(uint32_t val)
+{
     g_airlink_pause = val;
-    if (g_airlink_pause_mutex == NULL) luat_airlink_pause_init();
-    if (val) 
+    if (g_airlink_pause)
     {
-        luat_rtos_mutex_lock(g_airlink_pause_mutex, 1000);
+        // LLOGD("airlink pause requested, attempting to acquire pause mutex");
+        if (g_airlink_pause_mutex == NULL)
+            luat_airlink_pause_init();
+        if (g_airlink_pause_mutex)
+        {
+            // 非阻塞尝试锁定,若失败再做短时重试,避免调用者被长时间阻塞
+            if (luat_rtos_mutex_lock(g_airlink_pause_mutex, 0) != 0)
+            {
+                for (int i = 0; i < 50; i++)
+                {
+                    if (luat_rtos_mutex_lock(g_airlink_pause_mutex, 20) == 0)
+                        break;
+                    luat_rtos_task_sleep(2);
+                }
+            }
+        }
     }
-    else 
+    else
     {
-        luat_rtos_mutex_unlock(g_airlink_pause_mutex);
+        // LLOGD("airlink resume requested, releasing pause mutex");
+        if (g_airlink_pause_mutex)
+        {
+            // 释放 mutex,唤醒等待
+            luat_rtos_mutex_unlock(g_airlink_pause_mutex);
+        }
     }
-} 
+}
 
 int luat_airlink_stop(int id)
 {

+ 7 - 4
components/airlink/src/task/luat_airlink_spi_master_task.c

@@ -33,7 +33,7 @@
 
 extern airlink_statistic_t g_airlink_statistic;
 extern uint32_t g_airlink_pause;
-extern void *g_airlink_pause_mutex;
+extern luat_rtos_mutex_t g_airlink_pause_mutex;
 
 // static uint8_t start;
 // static uint8_t slave_rdy;
@@ -295,12 +295,15 @@ __USER_FUNC_IN_RAM__ void airlink_wait_and_prepare_data(uint8_t *txbuff)
         {
             if (g_airlink_pause_mutex)
             {
-                luat_rtos_mutex_lock(g_airlink_pause_mutex, 1000);
-                luat_rtos_mutex_unlock(g_airlink_pause_mutex);   // 被unlock唤醒后, 再立即unlock一次, 防止死锁
+                // LLOGD("airlink entering pause, waiting on mutex");
+                luat_rtos_mutex_lock(g_airlink_pause_mutex, LUAT_WAIT_FOREVER);
+                // LLOGD("airlink resumed from pause");
+                luat_rtos_mutex_unlock(g_airlink_pause_mutex);  // 立即释放,避免占用
             }
             else
             {
-                while (g_airlink_pause)
+                // 若未创建则轮询等待
+                while (g_airlink_pause) 
                 {
                     LLOGD("airlink spi 交互暂停中,允许主控休眠, 监测周期1000ms");
                     luat_rtos_task_sleep(1000);