4G LTE 模組狀態流程:`_AT_SESSION_WAIT_TO_GET_GPS`
`_AT_SESSION_WAIT_TO_GET_GPS` 會話狀態的主要目的是在獲取 GPS 資訊之前,作為一個等待和判斷點,根據不同的條件決定下一步的操作。它是一個**優先級判斷**的邏輯,確保重要的任務(如數據發送或重新登入)能夠優先執行,而週期性任務(如 GPS 獲取和命令輪詢)則在空閒時進行。
進入 `_AT_SESSION_WAIT_TO_GET_GPS` 狀態
判斷 1:是否有資料發送請求? (`_modem.lte_4G_TX_flag == 1`)
↓
**是 (Yes):**
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ 切換至 `_AT_SESSION_TX` 狀態 (執行資料發送)
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由 `_AT_SESSION_TX` 決定下一個狀態)
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ 切換至 `_AT_SESSION_TX` 狀態 (執行資料發送)
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由 `_AT_SESSION_TX` 決定下一個狀態)
**否 (No):**
進入下一個判斷。
進入下一個判斷。
↓
判斷 2:是否有重新登入請求? (`chk_relog_request()`)
↓
**是 (Yes):**
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ 切換至 `_AT_SESSION_LOG_OUT_IN` 狀態 (執行 MQTT 登出再登入)
→ 設定 `_connected = 0`
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由 `_AT_SESSION_LOG_OUT_IN` 決定下一個狀態)
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ 切換至 `_AT_SESSION_LOG_OUT_IN` 狀態 (執行 MQTT 登出再登入)
→ 設定 `_connected = 0`
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由 `_AT_SESSION_LOG_OUT_IN` 決定下一個狀態)
**否 (No):**
進入下一個判斷。
進入下一個判斷。
↓
判斷 3:GPS 時間到 且 輪詢時間到?
(`chk_timeup_ms(GPS_Tick, GPS_Read_Time)` AND `chk_timeup_ms(Polling_Tick, 5_Sec)`)
(`chk_timeup_ms(GPS_Tick, GPS_Read_Time)` AND `chk_timeup_ms(Polling_Tick, 5_Sec)`)
↓
**是 (Yes):**
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ **判斷:上次執行的是否為 GPS 獲取?** (`_prev_action_gps == 1`)
**是**: 切換至 `_AT_SESSION_POLLING` 狀態 (輪詢),設定 `_prev_action_gps = 0`
**否**: 切換至 `_AT_SESSION_GET_GPS` 狀態 (GPS 獲取),設定 `_prev_action_gps = 1`
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由相應狀態決定下一個狀態)
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ **判斷:上次執行的是否為 GPS 獲取?** (`_prev_action_gps == 1`)
**是**: 切換至 `_AT_SESSION_POLLING` 狀態 (輪詢),設定 `_prev_action_gps = 0`
**否**: 切換至 `_AT_SESSION_GET_GPS` 狀態 (GPS 獲取),設定 `_prev_action_gps = 1`
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由相應狀態決定下一個狀態)
**否 (No):**
進入下一個判斷。
進入下一個判斷。
↓
判斷 4:僅輪詢時間到? (`chk_timeup_ms(Polling_Tick, 5_Sec)`)
↓
**是 (Yes):**
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ 設定 `_prev_action_gps = 0`
→ 切換至 `_AT_SESSION_POLLING` 狀態
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由 `_AT_SESSION_POLLING` 決定下一個狀態)
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ 設定 `_prev_action_gps = 0`
→ 切換至 `_AT_SESSION_POLLING` 狀態
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由 `_AT_SESSION_POLLING` 決定下一個狀態)
**否 (No):**
進入下一個判斷。
進入下一個判斷。
↓
判斷 5:僅 GPS 時間到? (`chk_timeup_ms(GPS_Tick, GPS_Read_Time)`)
↓
**是 (Yes):**
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ 設定 `_prev_action_gps = 1`
→ 切換至 `_AT_SESSION_GET_GPS` 狀態
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由 `_AT_SESSION_GET_GPS` 決定下一個狀態)
嘗試獲取模組信號量 (`acquireSemaObj(_OWNER_MODEM)`)
若成功獲取:
→ 設定 `_prev_action_gps = 1`
→ 切換至 `_AT_SESSION_GET_GPS` 狀態
(執行完畢後回到 `_AT_SESSION_WAIT_TO_GET_GPS` 或由 `_AT_SESSION_GET_GPS` 決定下一個狀態)
**否 (No):**
回到 `_AT_SESSION_WAIT_TO_GET_GPS` 狀態,等待下一個循環判斷。
回到 `_AT_SESSION_WAIT_TO_GET_GPS` 狀態,等待下一個循環判斷。
優先級總結
在 `_AT_SESSION_WAIT_TO_GET_GPS` 狀態中,判斷和切換的邏輯遵循以下優先級:
- **資料發送 (Tx)**:最高優先級,確保數據及時上傳。
- **重新登入 (Relog)**:次高優先級,維持模組連線穩定性。
- **GPS 獲取與命令輪詢同時到期**:這兩個任務交替執行,以平衡資源使用。
- **僅命令輪詢 (Polling)**:在沒有更高優先級任務且輪詢時間到時執行。
- **僅 GPS 獲取**:在所有更高優先級任務都已處理完畢且 GPS 時間到時執行。
相關程式碼片段 (僅供參考)
case _AT_SESSION_WAIT_TO_GET_GPS:
if (_modem.lte_4G_TX_flag == 1) {
//enter the TX session
if(acquireSemaObj(_OWNER_MODEM))
switchATSession(_AT_SESSION_TX);
} else if(chk_relog_request()) {
if(acquireSemaObj(_OWNER_MODEM)) {
switchATSession(_AT_SESSION_LOG_OUT_IN);
_connected = 0; //disconnecting.....
#ifdef _RUN_TIME_DEBUG_ON
outputDbgMsg("start re-log sequence......\r\n");
#endif
}
} else if(chk_timeup_ms(timer1ms,at_cmd_poll_gps_tick, _modem.at_gps_read_time) && chk_timeup_ms(timer1ms, at_cmd_polling_tick, 5*1000)){
if(acquireSemaObj(_OWNER_MODEM)) {
if(_prev_action_gps) {
switchATSessionK(_AT_SESSION_POLLING);
_prev_action_gps = 0;
#ifdef _RUN_TIME_DEBUG_ON
outputDbgMsg("msg+++\r\n");
#endif
}else{
switchATSession(_AT_SESSION_GET_GPS);
_prev_action_gps = 1;
#ifdef _RUN_TIME_DEBUG_ON
outputDbgMsg("gps+++\r\n");
#endif
}
}
} else if (chk_timeup_ms(timer1ms, at_cmd_polling_tick, 5*1000)) {
if(acquireSemaObj(_OWNER_MODEM)) {
_prev_action_gps = 0;
switchATSessionK(_AT_SESSION_POLLING);
#ifdef _RUN_TIME_DEBUG_ON
outputDbgMsg("poll...\r\n");
#endif
}
} else if (chk_timeup_ms(timer1ms,at_cmd_poll_gps_tick, _modem.at_gps_read_time)) {
if(acquireSemaObj(_OWNER_MODEM)) {
_prev_action_gps = 1;
switchATSessionK(_AT_SESSION_GET_GPS);
#ifdef _RUN_TIME_DEBUG_ON
outputDbgMsg("gps...\r\n");
#endif
}
}
break;
沒有留言:
張貼留言