Pārlūkot izejas kodu

优化CAN消息发送,补充队列机制,防止并发发送导致控制失效

bjb 3 mēneši atpakaļ
vecāks
revīzija
e8a8e07b3d

+ 8 - 0
.idea/deploymentTargetSelector.xml

@@ -4,6 +4,14 @@
     <selectionStates>
       <SelectionState runConfigName="app">
         <option name="selectionMode" value="DROPDOWN" />
+        <DropdownSelection timestamp="2026-02-03T02:16:51.316874600Z">
+          <Target type="DEFAULT_BOOT">
+            <handle>
+              <DeviceId pluginId="Default" identifier="serial=192.168.1.150:5555;connection=46f07cc6" />
+            </handle>
+          </Target>
+        </DropdownSelection>
+        <DialogSelection />
       </SelectionState>
     </selectionStates>
   </component>

+ 20 - 7
app/src/main/java/com/iscs/comm/CtrlActivity.kt

@@ -3,7 +3,6 @@ package com.iscs.comm
 import android.content.Context
 import android.content.Intent
 import android.os.Bundle
-import android.util.Log
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
 import androidx.activity.enableEdgeToEdge
@@ -122,7 +121,8 @@ class CtrlActivity : ComponentActivity() {
                                     rfid.value = it.rfid
                                     if (it.isChanged && rfid.value.isNotEmpty() && rfid.value != lastRFID) {
                                         lastRFID = rfid.value
-                                        dev.ctrlSlotLock(state.ch, true).writeByFrame()
+                                        // 硬件逻辑已经存在
+                                        dev.ctrlSlotLockAndCharge(state.ch, true, true).writeByFrame()
                                     } else if (rfid.value.isEmpty()) {
                                         lastRFID = ""
                                     }
@@ -156,14 +156,26 @@ class CtrlActivity : ComponentActivity() {
                             }
                             Spacer(modifier = Modifier.weight(1f))
                             Row {
-                                Button({ dev.ctrlSlotLock(state.ch, false).writeByFrame() }) { Text("打开锁") }
+                                Button(
+                                    { dev.ctrlSlotLockAndCharge(state.ch, false, false).writeByFrame() },
+                                    contentPadding = PaddingValues(horizontal = 6.dp, vertical = 0.dp)
+                                ) { Text("打开锁") }
                                 Spacer(modifier = Modifier.weight(1f))
-                                Button({ dev.ctrlSlotLock(state.ch, true).writeByFrame() }) { Text("关闭锁") }
+                                Button(
+                                    { dev.ctrlSlotLockAndCharge(state.ch, true, true).writeByFrame() },
+                                    contentPadding = PaddingValues(horizontal = 6.dp, vertical = 0.dp)
+                                ) { Text("关闭锁") }
                             }
                             Row {
-                                Button({ dev.ctrlSlotCharge(state.ch, true).writeByFrame() }) { Text("开充电") }
+                                Button(
+                                    { dev.ctrlSlotCharge(state.ch, true).writeByFrame() },
+                                    contentPadding = PaddingValues(horizontal = 6.dp, vertical = 0.dp)
+                                ) { Text("开充电") }
                                 Spacer(modifier = Modifier.weight(1f))
-                                Button({ dev.ctrlSlotCharge(state.ch, false).writeByFrame() }) { Text("关充电") }
+                                Button(
+                                    { dev.ctrlSlotCharge(state.ch, false).writeByFrame() },
+                                    contentPadding = PaddingValues(horizontal = 6.dp, vertical = 0.dp)
+                                ) { Text("关充电") }
                             }
                         }
                     }
@@ -208,7 +220,8 @@ class CtrlActivity : ComponentActivity() {
                                     // 这里可以做一些其他逻辑,比如如果当前有锁存在,但是没上锁,这里可执行上锁操作
                                     if (it.isChanged && rfid.value.isNotEmpty() && rfid.value != lastRFID) {
                                         lastRFID = rfid.value
-                                        dev.ctrlSlotLock(state.ch, true).writeByFrame()
+                                        // 硬件逻辑已存在
+                                        // dev.ctrlSlotLock(state.ch, true).writeByFrame()
                                     } else if (rfid.value.isEmpty()) {
                                         lastRFID = ""
                                     }

+ 26 - 8
transport/src/main/java/com/iscs/comm/manager/CanManager.kt

@@ -11,6 +11,9 @@ import com.iscs.comm.utils.ShellTools
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.TimeoutCancellationException
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withTimeout
 import java.util.concurrent.ConcurrentHashMap
@@ -33,9 +36,29 @@ class CanManager(private val port: String = "can0", private val bitrate: Int = 1
     // JNI层CanSocket的id
     private var portId = -1
 
-    // 待响应式的请求数据接收池
+    // 发送补充队列,防止并发Can无法正常处理数据,最大容积200个
+    private val sendQueue = Channel<Frame>(capacity = Channel.BUFFERED)
+
+    // 响应式的请求数据接收池
     private val receiverPool = ConcurrentHashMap<String, CompletableDeferred<Frame>>()
 
+    // 构建工作线程并对其进行初始化操作
+    init {
+        scope.launch(Dispatchers.IO) {
+            for (frame in sendQueue) {
+                // 执行消息发送
+                val ret = NativeCan.canWrite(portId, frame.cmd, frame.data, frame.data.size)
+                if (ret < 0 && isOpened) {
+                    isOpened = false
+                    close()
+                    // 这里通知外部CAN连接中断了,重连操作交给外部使用
+                    ISCSLog.e(TAG, "CAN write failed, execute close")
+                }
+                delay(20)
+            }
+        }
+    }
+
     /**
      * 打开CAN口操作
      *
@@ -53,6 +76,7 @@ class CanManager(private val port: String = "can0", private val bitrate: Int = 1
     }
 
     override fun close() {
+        sendQueue.close()
         NativeCan.canClose(portId)
         portId = -1
     }
@@ -65,13 +89,7 @@ class CanManager(private val port: String = "can0", private val bitrate: Int = 1
     override suspend fun write(frame: Frame) {
         if (portId <= 0) return
         frame.frameFrom = CommType.CAN
-        val ret = NativeCan.canWrite(portId, frame.cmd, frame.data, frame.data.size)
-        if (ret < 0 && isOpened) {
-            isOpened = false
-            close()
-            // 这里通知外部CAN连接中断了,重连操作交给外部使用
-            ISCSLog.e(TAG, "CAN write failed, execute close")
-        }
+        sendQueue.trySend(frame)
     }
 
     /**