這幾天發現我佈署在 Pi 4 上的 OpenClaw 沒有回應, 檢查發現是 WiFi 網路連線中斷所致, 本篇旨在紀錄如何防止此情況的做法. 本系列全部測試文章索引參考 :
樹莓派 (特別是 Pi 4B 內建的 Cypress/Broadcom 無線晶片) 在長時間運作時斷線且無法自行恢復, 此乃 Linux 嵌入式環境中非常經典的硬體與驅動問題, 以下是我詢問 Gemini 的摘要 :
- WiFi 晶片省電休眠 :
樹莓派作業系統預設會開啟 wlan0 的無線節電功能, 當一陣子沒有網路流量時, 晶片會進入低功耗睡眠狀態, 往往在 AP (路由器) 發送探測訊號時沒能及時回應導致路由器判定離線. - 底層驅動狀態僵死 :
當連線突然中斷時, 晶片硬體或底層驅動可能仍以為介面處於連線中, 但上層網路服務(NetworkManager 或 wpa_supplicant) 已經掉封包或無法更新 DHCP 租約. 因為系統沒有明確收到硬體斷線的中斷信號, 自動重連邏輯就根本不會被觸發, 介面就卡死在有 IP 或假連線, 但實際上 ping 不出去的假死狀態. - 路由器自動漫遊或頻段切換 :
家用 Wi-Fi 若將 2.4GHz 與 5GHz 合併為同一個 SSID, 路由器嘗試強制叫樹莓派切換頻段時, 樹莓派網卡很容易切換失敗並直接卡死.
避免此問題的解決辦法如下 :
1. 永久關閉 Wi-Fi 省電模式 :
Gemini 說先用下列指令檢查樹莓派目前的省電模式設定 :
pi@pi4b:~ $ iw dev wlan0 get power_save
Power save : on
用 nano 開啟開機介面設定檔 /etc/rc.local :
pi@pi4b:~ $ sudo nano /etc/rc.local
輸入如下內容後按 Ctrl + O 存檔再按 Ctrl + X 跳出 nano :
iw dev wlan0 set power_save off
exit 0
但再次檢查節能設定還是 on :
pi@pi4b:~ $ iw dev wlan0 get power_save
Power save : on
原來 Raspberry Pi OS 自 Debian 12 Bookworm 之後已經全面改用 NetworkManager 來掌管網路, 而 NetworkManager 自身的電源管理設定優先級高於 iw, 所以即使手動或透過 rc.local 關閉, NetworkManager 也會在背景自動把它改回 power_save on.
解決方法是直接在 NetworkManager 全域設定中關閉 Wi-Fi 省電, 執行下列指令直接新增一個全域覆蓋設定檔 (數值 2 在 NetworkManager 中代表 NM_SETTING_WIRELESS_POWERSAVE_DISABLE, 徹底停用 WiFi 節能) :
pi@pi4b:~ $ sudo tee /etc/NetworkManager/conf.d/default-wifi-powersave-off.conf << 'EOF'
[connection]
wifi.powersave = 2
EOF
然後重新載入網路管理服務讓設定生效 :
pi@pi4b:~ $ sudo systemctl restart NetworkManager
再次檢查節能設定就會變成 off 了.
pi@pi4b:~ $ iw dev wlan0 get power_save
Power save : off
2. 建立輕量級的 WiFi 看門狗 (Watchdog) 腳本程式 :
用 nano 編輯一個 wifi-watchdog.sh 腳本程式 :
pi@pi4b:~ $ sudo nano /usr/local/bin/wifi-watchdog.sh
貼上如下程式後按 Ctrl + O 存檔再按 Ctrl + X 跳出 nano :
#!/bin/bash
# 探測目標(可填路由器 IP 或 8.8.8.8)
TARGET="8.8.8.8"
# ping 3 次,若全數失敗則重啟無線網路
if ! ping -c 3 -W 5 "$TARGET" > /dev/null 2>&1; then
echo "[$(date)] WiFi connection lost, resetting network..." >> /var/log/wifi-watchdog.log
# 優先使用 NetworkManager 重新連線
if command -v nmcli > /dev/null 2>&1; then
nmcli device disconnect wlan0
sleep 2
nmcli device connect wlan0
else
# 備用方案:重啟介面
ip link set wlan0 down
sleep 2
ip link set wlan0 up
fi
fi
此腳本執行時會用 ping 對外發送 3 次 ICMP 封包 (預設目標為 8.8.8.8), 只要有任何 1 次成功收到回應就代表網路暢通, 腳本直接安靜結束不做任何動作. 若連續 3 次 ping 都失敗 (完全失聯), 就會觸發修復動作, 第一時間先在 /var/log/wifi-watchdog.log 寫入帶有時間戳記的斷線紀錄方便日後排查問題.
然後自動重啟網卡恢復連線, 若系統使用 nmcli 就直接執行 disconnect wlan0 再 connect wlan0, 讓 NetworkManager 重新觸發握手與 DHCP 獲取 IP; 若無 nmcli 則改用底層指令強制將網卡帶下再重啟 (p link set wlan0 down / up).
接下來賦予此腳本執行權限 :
pi@pi4b:~ $ sudo chmod +x /usr/local/bin/wifi-watchdog.sh
設定系統管理排程 crontab 中 :
pi@pi4b:~ $ sudo crontab -e
在最底下加入如下排程後按 Ctrl + O 存檔再按 Ctrl + X 跳出 nano :
*/3 * * * * /usr/local/bin/wifi-watchdog.sh > /dev/null 2>&1
這樣系統就會每 3 分鐘執行一次上面腳本檢查 WiFi 連線, 若發現樹莓派 Wi-Fi 假死或斷線時就自動修復連線.
用下列指令可直接檢查看門狗專屬的紀錄檔 :
pi@pi4b:~ $ cat /var/log/wifi-watchdog.log
若回應檔案不存在或內容是空的, 代表目前 Wi-Fi 訊號很穩定, 每次 ping 8.8.8.8 都有通, 因此腳本安靜結束完全沒有發生斷線重連; 反之若看到帶有時間戳記的 "WiFi connection lost, resetting network...", 表示曾有斷線並成功觸發修復.
也可用 journalctl 指令查詢 Cron 服務日誌 :
pi@pi4b:~ $ sudo journalctl -u cron | grep wifi-watchdog | tail -n 10
若看到每隔 3 分鐘就有一筆如下的執行輸出, 表示 crontab 排程有正常運作 :