在信號發(fā)生器控制腳本中,錯誤處理是確保系統(tǒng)穩(wěn)定性和可維護性的關(guān)鍵環(huán)節(jié)。以下是針對信號發(fā)生器腳本的錯誤處理機制設(shè)計,涵蓋異常捕獲、日志記錄、重試機制、設(shè)備狀態(tài)檢查等核心方法,并提供Python和C++的代碼示例。
一、錯誤處理的核心場景
- 設(shè)備通信失敗(如網(wǎng)絡(luò)斷開、USB連接異常)
- 參數(shù)越界(如頻率/幅度超出設(shè)備支持范圍)
- 命令執(zhí)行超時(如設(shè)備無響應(yīng))
- 資源沖突(如多個線程同時訪問設(shè)備)
- 意外狀態(tài)(如設(shè)備鎖相失敗、過熱保護)
二、Python中的錯誤處理實現(xiàn)
1. 基礎(chǔ)異常捕獲
| import time |
| from your_signal_generator_lib import SignalGenerator, DeviceError |
|
| def safe_configure_channel(sg, channel, freq, amp): |
| try: |
| sg.set_frequency(channel, freq) |
| sg.set_amplitude(channel, amp) |
| except DeviceError as e: |
| print(f"Channel {channel}配置失敗: {str(e)}") |
| # 可選:記錄日志或觸發(fā)報警 |
| except ValueError as e: |
| print(f"參數(shù)錯誤 (Channel {channel}): {str(e)}") |
| except Exception as e: |
| print(f"未知錯誤 (Channel {channel}): {str(e)}") |
| raise |
|
| # 使用示例 |
| sg = SignalGenerator("192.168.1.100") |
| try: |
| safe_configure_channel(sg, 1, 10e6, -5) |
| safe_configure_channel(sg, 2, 1e9, 0) |
| except Exception as e: |
| print(f"腳本終止: {str(e)}") |
2. 超時與重試機制
| import time |
| from threading import Lock |
|
| def configure_with_retry(sg, channel, freq, amp, max_retries=3, timeout=5): |
| lock = Lock() |
| for attempt in range(max_retries): |
| try: |
| with lock: |
| sg.set_frequency(channel, freq, timeout=timeout) |
| sg.set_amplitude(channel, amp, timeout=timeout) |
| return True |
| except DeviceError as e: |
| print(f"Attempt {attempt + 1} failed: {str(e)}") |
| time.sleep(1) |
| except TimeoutError: |
| print("設(shè)備響應(yīng)超時,重置連接...") |
| sg.reconnect() |
| return False |
|
| # 使用示例 |
| if not configure_with_retry(sg, 1, 5e6, -10): |
| print("配置失敗,執(zhí)行備用方案...") |
3. 日志記錄與告警
| import logging |
|
| # 配置日志 |
| logging.basicConfig( |
| filename="signal_generator.log", |
| level=logging.ERROR, |
| format="%(asctime)s - %(levelname)s - %(message)s" |
| ) |
|
| def log_and_raise(error_msg): |
| logging.error(error_msg) |
| raise RuntimeError(error_msg) |
|
| try: |
| sg.set_frequency(1, 1e10) |
| except ValueError as e: |
| log_and_raise(f"嚴重參數(shù)錯誤: {str(e)}") |
三、C++中的錯誤處理實現(xiàn)
1. 異常與錯誤碼結(jié)合
| #include <iostream> |
| #include <stdexcept> |
| #include <mutex> |
| #include "signal_generator.h" |
|
| std::mutex sg_mutex; |
|
| void safeConfigureChannel(SignalGenerator& sg, int channel, double freq, double amp) { |
| try { |
| std::lock_guard<std::mutex> lock(sg_mutex); |
| if (freq > sg.getMaxFrequency()) { |
| throw std::out_of_range("Frequency exceeds device limit"); |
| } |
| sg.setFrequency(channel, freq); |
| sg.setAmplitude(channel, amp); |
| } catch (const std::exception& e) { |
| std::cerr << "Error (Channel " << channel << "): " << e.what() << std::endl; |
| // 可選:記錄到文件或觸發(fā)回調(diào) |
| } |
| } |
|
| // 使用示例 |
| int main() { |
| SignalGenerator sg("192.168.1.100"); |
| try { |
| safeConfigureChannel(sg, 1, 1e6, -10); |
| safeConfigureChannel(sg, 2, 1e10, 0); |
| } catch (...) { |
| std::cerr << "Unhandled exception in main" << std::endl; |
| } |
| return 0; |
| } |
2. 重試與狀態(tài)檢查
| #include <chrono> |
| #include <thread> |
|
| bool configureWithRetry(SignalGenerator& sg, int channel, double freq, double amp, int maxRetries = 3) { |
| for (int i = 0; i < maxRetries; ++i) { |
| try { |
| std::lock_guard<std::mutex> lock(sg_mutex); |
| if (!sg.isConnected()) { |
| sg.reconnect(); |
| } |
| sg.setFrequency(channel, freq); |
| sg.setAmplitude(channel, amp); |
| return true; |
| } catch (const std::exception& e) { |
| std::cerr << "Attempt " << i + 1 << " failed: " << e.what() << std::endl; |
| std::this_thread::sleep_for(std::chrono::seconds(1)); |
| } |
| } |
| return false; |
| } |
四、高級錯誤處理策略
1. 設(shè)備狀態(tài)監(jiān)控與自動恢復
| def monitor_and_recover(sg, check_interval=60): |
| while True: |
| try: |
| status = sg.get_status() |
| if "ERROR" in status: |
| print("檢測到設(shè)備錯誤,嘗試恢復...") |
| sg.reset() |
| time.sleep(10) |
| except Exception as e: |
| print(f"監(jiān)控線程異常: {str(e)}") |
| time.sleep(check_interval) |
|
| # 在后臺啟動監(jiān)控線程 |
| import threading |
| threading.Thread(target=monitor_and_recover, args=(sg,), daemon=True).start() |
2. 上下文管理器(Python)
| from contextlib import contextmanager |
|
| @contextmanager |
| def signal_generator_session(sg): |
| try: |
| yield sg |
| except DeviceError as e: |
| print(f"操作失敗: {str(e)}") |
| sg.disconnect() |
| raise |
| finally: |
| sg.disconnect() |
|
| # 使用示例 |
| with signal_generator_session(SignalGenerator("192.168.1.100")) as sg: |
| sg.set_frequency(1, 1e6) |
五、關(guān)鍵注意事項
- 線程安全:
- 多線程環(huán)境下,所有設(shè)備操作必須通過鎖或隊列同步。
- 異常類型:
- 區(qū)分可恢復錯誤(如臨時通信中斷)和不可恢復錯誤(如參數(shù)越界)。
- 日志重要性:
- 記錄完整的錯誤上下文(時間、參數(shù)、設(shè)備狀態(tài))以便排查。
- 資源清理:
- 使用
try/finally或上下文管理器確保設(shè)備連接釋放。
六、總結(jié)
- Python:利用
try/except、日志模塊和上下文管理器實現(xiàn)健壯性。 - C++:結(jié)合異常、錯誤碼和RAII模式管理資源。
- 通用策略:
- 捕獲所有預期異常(如設(shè)備超時、參數(shù)錯誤)。
- 對關(guān)鍵操作實現(xiàn)重試機制。
- 通過日志和監(jiān)控持續(xù)跟蹤設(shè)備狀態(tài)。
- 設(shè)計故障恢復流程(如自動重連、回退默認值)。
通過完善的錯誤處理,信號發(fā)生器腳本可以從偶發(fā)故障中自動恢復,顯著提升自動化測試或生產(chǎn)環(huán)境的可靠性。