嵌入式开发是一项复杂且具有挑战性的工作,尤其是在调试过程中,开发者需要面对各种硬件与软件的交互问题。为了有效提高调试效率,使用自动化工具和脚本可以大大简化流程。在这篇文章中,我将分享几种常见的 Python 脚本,它们能够帮助嵌入式开发者进行调试优化。我们将涵盖串口日志收集、内存监控、性能测试、日志分析等方面的内容。
一、功能分享:
1. 串口日志收集脚本
在嵌入式系统开发中,串口通常用于输出调试信息。使用 Python 脚本可以自动化收集这些日志数据,实时监控并分析串口数据。
ps:这个脚本通过 pyserial
库与嵌入式设备建立串口连接,实时读取串口输出的数据。如果发现包含 "ERROR" 的信息,脚本会停止并输出错误提示。此脚本适用于实时监控和自动化日志收集,帮助调试过程中捕捉异常
python">import serial
import timedef collect_uart_data(port='/dev/ttyUSB0', baudrate=115200, timeout=1):# 打开串口连接with serial.Serial(port, baudrate, timeout=timeout) as ser:print(f"Connected to {port} at {baudrate} baudrate.")while True:if ser.in_waiting > 0:data = ser.readline().decode('utf-8').strip() # 读取串口数据print(f"Received: {data}")if "ERROR" in data: # 判断是否有错误信息print("Error detected!")breaktime.sleep(0.1)if __name__ == "__main__":collect_uart_data()
2. 实时内存使用监控脚本
在嵌入式系统中,内存使用情况对系统的稳定性至关重要。很多时候系统的崩溃无外乎就两个原因:第一是系统时序的紊乱;第二就是内存泄漏和过度使用可能会导致系统崩溃。实时监控系统内存使用情况,可以很大程度上改善这个现象。
ps:使用 psutil
库实时监控系统内存的使用情况。如果内存使用超过设定的阈值(例如这里我设置的80%),则输出警告信息。可以帮助开发者避免因内存不足而导致的系统崩溃,尤其在内存紧张的嵌入式系统中。
python">import psutil
import timedef monitor_memory_usage():while True:memory = psutil.virtual_memory() # 获取内存使用情况print(f"Memory Usage: {memory.percent}%")if memory.percent > 80: # 如果内存使用超过80%print("Warning: Memory usage is too high!")time.sleep(1)if __name__ == "__main__":monitor_memory_usage()
3. 自动化日志分析
随着嵌入式开发项目的推进,生成的日志文件往往会非常庞大。通过 Python 脚本,我们可以自动分析这些日志文件,快速筛选出错误、警告或其他重要信息,节省人工查找的时间。
ps:该通过正则表达式查找日志文件中的错误信息(如 "ERROR")和警告信息(如 "WARNING")。开发者可以快速定位到日志中的问题,而无需手动逐行检查。
python">import redef analyze_log_file(log_file):with open(log_file, 'r') as file:logs = file.readlines()error_pattern = re.compile(r'ERROR') # 查找错误日志warning_pattern = re.compile(r'WARNING') # 查找警告日志error_logs = [line for line in logs if error_pattern.search(line)]warning_logs = [line for line in logs if warning_pattern.search(line)]if error_logs:print("Errors found in the log:")for error in error_logs:print(error.strip())else:print("No errors found.")if warning_logs:print("\nWarnings found in the log:")for warning in warning_logs:print(warning.strip())else:print("No warnings found.")if __name__ == "__main__":analyze_log_file('device_log.txt') # 提供日志文件路径
4. 性能测试脚本
性能是嵌入式系统中非常关键的一个方面。通过对代码执行时间的监测,开发者可以发现性能瓶颈并进行优化。以下 Python 脚本模拟了对某个函数的性能测试。
ps:通过 time.time()
来测量函数执行的时间,帮助开发者发现函数执行的瓶颈。通过这种方式,可以对嵌入式系统中的关键代码进行性能评估和优化。
python">import timedef test_function():# 模拟耗时的任务total = 0for i in range(1000000):total += ireturn totaldef measure_performance(func):start_time = time.time() # 获取当前时间result = func()end_time = time.time() # 结束时间elapsed_time = end_time - start_time # 计算时间差print(f"Function executed in {elapsed_time:.6f} seconds")return resultif __name__ == "__main__":measure_performance(test_function)
二、应用与迁移:
为了方便可以直接迁移到不同的嵌入式项目中,进行实际应用。以下是一些建议,帮助调试脚本,使它们能够更好地适应各种嵌入式项目。(大佬忽略)
1. 模块化设计与功能封装
将不同的调试任务功能封装成独立的模块(Python 类或函数),这样可以确保每个脚本只负责一个特定的任务。通过模块化设计,脚本可以方便地在不同的项目中调用和复用。
例如,日志收集、内存监控、性能测试等功能可以分别封装成不同的 Python 模块。用户只需要根据项目需要导入相应的模块。
python"># uart_logger.pyimport serial
import timeclass UartLogger:def __init__(self, port='/dev/ttyUSB0', baudrate=115200, timeout=1):self.port = portself.baudrate = baudrateself.timeout = timeoutself.ser = Nonedef start_logging(self):self.ser = serial.Serial(self.port, self.baudrate, timeout=self.timeout)print(f"Connected to {self.port} at {self.baudrate} baudrate.")while True:if self.ser.in_waiting > 0:data = self.ser.readline().decode('utf-8').strip() # 读取串口数据print(f"Received: {data}")if "ERROR" in data: # 判断是否有错误信息print("Error detected!")breaktime.sleep(0.1)def stop_logging(self):if self.ser:self.ser.close()print("Connection closed.")
from uart_logger import UartLogger
logger = UartLogger(port='/dev/ttyUSB1', baudrate=9600)
logger.start_logging()
直接使用UartLogger
类封装了串口日志收集功能,使用时只需创建该类的实例并调用 start_logging()
方法即可。stop_logging()
方法用于关闭串口连接
2. 配置文件与参数化
为了增强脚本的灵活性,可以通过配置文件(如 .ini
、.json
或 .yaml
格式的文件)来管理不同项目的配置参数。这样,可以通过修改配置文件而不需要改动代码本身,从而在不同的项目中快速适配。
示例:配置文件 (config.json
)
{
"uart": {
"port": "/dev/ttyUSB0",
"baudrate": 115200,
"timeout": 1
},
"memory_monitor": {
"threshold": 80
}
}
python"># config.py
import jsondef load_config(config_file='config.json'):with open(config_file, 'r') as f:config = json.load(f)return config# uart_logger.py
from config import load_config
import serial
import timeclass UartLogger:def __init__(self, config):self.port = config['uart']['port']self.baudrate = config['uart']['baudrate']self.timeout = config['uart']['timeout']self.ser = Nonedef start_logging(self):self.ser = serial.Serial(self.port, self.baudrate, timeout=self.timeout)print(f"Connected to {self.port} at {self.baudrate} baudrate.")while True:if self.ser.in_waiting > 0:data = self.ser.readline().decode('utf-8').strip() # 读取串口数据print(f"Received: {data}")if "ERROR" in data: # 判断是否有错误信息print("Error detected!")breaktime.sleep(0.1)def stop_logging(self):if self.ser:self.ser.close()print("Connection closed.")if __name__ == "__main__":config = load_config()logger = UartLogger(config)logger.start_logging()
# main.py
from uart_logger import UartLogger
from config import load_configconfig = load_config('config.json')
logger = UartLogger(config)
logger.start_logging()
解释:在这个例子中,config.json
文件用来存储串口连接的相关配置。通过 load_config
函数加载配置后,UartLogger
类可以使用这些配置参数,确保脚本能够在不同的项目中灵活配置和使用。