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;
沒有留言:
張貼留言