在信号发生器控制脚本中,错误处理是确保系统稳定性和可维护性的关键环节。以下是针对信号发生器脚本的错误处理机制设计,涵盖异常捕获、日志记录、重试机制、设备状态检查等核心方法,并提供Python和C++的代码示例。
一、错误处理的核心场景
- 设备通信失败(如网络断开、USB连接异常)
- 参数越界(如频率/幅度超出设备支持范围)
- 命令执行超时(如设备无响应)
- 资源冲突(如多个线程同时访问设备)
- 意外状态(如设备锁相失败、过热保护)
二、Python中的错误处理实现
1. 基础异常捕获
| 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)}") |
| # 可选:记录日志或触发报警 |
| except ValueError as e: |
| print(f"参数错误 (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("设备响应超时,重置连接...") |
| sg.reconnect() |
| return False |
|
| # 使用示例 |
| if not configure_with_retry(sg, 1, 5e6, -10): |
| print("配置失败,执行备用方案...") |
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"严重参数错误: {str(e)}") |
三、C++中的错误处理实现
1. 异常与错误码结合
| #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; |
| // 可选:记录到文件或触发回调 |
| } |
| } |
|
| // 使用示例 |
| 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. 重试与状态检查
| #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. 设备状态监控与自动恢复
| def monitor_and_recover(sg, check_interval=60): |
| while True: |
| try: |
| status = sg.get_status() |
| if "ERROR" in status: |
| print("检测到设备错误,尝试恢复...") |
| sg.reset() |
| time.sleep(10) |
| except Exception as e: |
| print(f"监控线程异常: {str(e)}") |
| time.sleep(check_interval) |
|
| # 在后台启动监控线程 |
| 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) |
五、关键注意事项
- 线程安全:
- 异常类型:
- 区分可恢复错误(如临时通信中断)和不可恢复错误(如参数越界)。
- 日志重要性:
- 记录完整的错误上下文(时间、参数、设备状态)以便排查。
- 资源清理:
- 使用
try/finally或上下文管理器确保设备连接释放。
六、总结
- Python:利用
try/except、日志模块和上下文管理器实现健壮性。 - C++:结合异常、错误码和RAII模式管理资源。
- 通用策略:
- 捕获所有预期异常(如设备超时、参数错误)。
- 对关键操作实现重试机制。
- 通过日志和监控持续跟踪设备状态。
- 设计故障恢复流程(如自动重连、回退默认值)。
通过完善的错误处理,信号发生器脚本可以从偶发故障中自动恢复,显著提升自动化测试或生产环境的可靠性。