부팅 시 serial packet이 전송되지 않는 버그 수정

This commit is contained in:
StevenBuzzi
2026-03-04 17:11:09 +09:00
parent 90c0a93a5e
commit 628f7544be
5 changed files with 141 additions and 15 deletions

View File

@@ -260,9 +260,11 @@ class MainActivity : ComponentActivity() {
// This prevents serial interrupts from stealing CPU during the first frame.
delay(200)
vm.txPacketOnce()
// IMPORTANT:
// rxPacketLoop() starts serial open() asynchronously.
// Start RX first so txPacketOnce() is less likely to run before FD is ready.
vm.rxPacketLoop()
vm.txPacketOnce()
vm.txPacketLoop()
Timber.d("System fully operational.")

View File

@@ -814,24 +814,47 @@ class MainViewModel @Inject constructor(
}
fun txPacketOnce() {
// viewModel init 으로 이동. 필요.
// 경고 정보 조회 (주기적 heart beat)
// repeatOnLifecycle은 Activity가 포그라운드에 있을 때로 한정지어, 특정 Lifecycle이 Trigger 되었을 때 동작하도록 만드는 block 임.
viewModelScope.launch(dispatcherProvider.io) {
// txPacketOnce is called during app startup.
// Because serial open() is started in rxPacketLoop() asynchronously,
// FD can still be -1 here (startup race). Wait briefly before first TX burst.
if (!waitUntilSerialReady()) {
Timber.e("txPacketOnce skipped: serial port is not ready (fd=%d)", serialPortRepository.getFD())
return@launch
}
// tx Version Read
txPacket(READ_WRITE.READ, CMD.VERSION, byteArrayOf(0x41.toByte()))
// viewModel init 으로 이동. 필요.
// 경고 정보 조회 (주기적 heart beat)
// repeatOnLifecycle은 Activity가 포그라운드에 있을 때로 한정지어, 특정 Lifecycle이 Trigger 되었을 때 동작하도록 만드는 block 임.
// tx Q-Switch Write
txPacket(READ_WRITE.WRITE, CMD.Q_SWITCH, qSwitch.value)
// tx Version Read
txPacket(READ_WRITE.READ, CMD.VERSION, byteArrayOf(0x41.toByte()))
// tx Guide Beam Write
txPacket(READ_WRITE.WRITE, CMD.GUIDE_BEAM, GuideBeam(value = getGuideBeamTxValue()))
// tx Q-Switch Write
txPacket(READ_WRITE.WRITE, CMD.Q_SWITCH, qSwitch.value)
// tx DCD_GAS Write (DEFAULT VALUE)
txPacket(READ_WRITE.WRITE, CMD.DCD_GAS, dcdGas.value.copy(status = 0x50))
// tx Guide Beam Write
txPacket(READ_WRITE.WRITE, CMD.GUIDE_BEAM, GuideBeam(value = getGuideBeamTxValue()))
// tx SPRAY_DCD Write (DEFAULT VALUE)
txPacket(READ_WRITE.WRITE, CMD.SPRAY_DCD, sprayDcd.value)
// tx DCD_GAS Write (DEFAULT VALUE)
txPacket(READ_WRITE.WRITE, CMD.DCD_GAS, dcdGas.value.copy(status = 0x50))
// tx SPRAY_DCD Write (DEFAULT VALUE)
txPacket(READ_WRITE.WRITE, CMD.SPRAY_DCD, sprayDcd.value)
}
}
private suspend fun waitUntilSerialReady(
timeoutMillis: Long = 2000L,
pollIntervalMillis: Long = 20L
): Boolean {
// Poll FD until open() completes, with a bounded timeout to avoid blocking forever.
val start = System.currentTimeMillis()
while (System.currentTimeMillis() - start < timeoutMillis) {
if (serialPortRepository.getFD() != -1) return true
delay(pollIntervalMillis)
}
return serialPortRepository.getFD() != -1
}
// Guide Beam step mapping (0~10)