嵌入式开发调试优化:使用 Python 脚本提升效率

发布于:2024-11-27 ⋅ 阅读:(135) ⋅ 点赞:(0)

        嵌入式开发是一项复杂且具有挑战性的工作,尤其是在调试过程中,开发者需要面对各种硬件与软件的交互问题。为了有效提高调试效率,使用自动化工具和脚本可以大大简化流程。在这篇文章中,我将分享几种常见的 Python 脚本,它们能够帮助嵌入式开发者进行调试优化。我们将涵盖串口日志收集、内存监控、性能测试、日志分析等方面的内容。

一、功能分享:

1. 串口日志收集脚本

        在嵌入式系统开发中,串口通常用于输出调试信息。使用 Python 脚本可以自动化收集这些日志数据,实时监控并分析串口数据。

        ps:这个脚本通过 pyserial 库与嵌入式设备建立串口连接,实时读取串口输出的数据。如果发现包含 "ERROR" 的信息,脚本会停止并输出错误提示。此脚本适用于实时监控和自动化日志收集,帮助调试过程中捕捉异常

import serial
import time

def 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!")
                    break
            time.sleep(0.1)

if __name__ == "__main__":
    collect_uart_data()

2. 实时内存使用监控脚本

        在嵌入式系统中,内存使用情况对系统的稳定性至关重要。很多时候系统的崩溃无外乎就两个原因:第一是系统时序的紊乱;第二就是内存泄漏和过度使用可能会导致系统崩溃。实时监控系统内存使用情况,可以很大程度上改善这个现象。

        ps:使用 psutil 库实时监控系统内存的使用情况。如果内存使用超过设定的阈值(例如这里我设置的80%),则输出警告信息。可以帮助开发者避免因内存不足而导致的系统崩溃,尤其在内存紧张的嵌入式系统中。

import psutil
import time

def 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")。开发者可以快速定位到日志中的问题,而无需手动逐行检查。

import re

def 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() 来测量函数执行的时间,帮助开发者发现函数执行的瓶颈。通过这种方式,可以对嵌入式系统中的关键代码进行性能评估和优化。

import time

def test_function():
    # 模拟耗时的任务
    total = 0
    for i in range(1000000):
        total += i
    return total

def 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 result

if __name__ == "__main__":
    measure_performance(test_function)

二、应用与迁移:

        为了方便可以直接迁移到不同的嵌入式项目中,进行实际应用。以下是一些建议,帮助调试脚本,使它们能够更好地适应各种嵌入式项目。(大佬忽略)

1. 模块化设计与功能封装

        将不同的调试任务功能封装成独立的模块(Python 类或函数),这样可以确保每个脚本只负责一个特定的任务。通过模块化设计,脚本可以方便地在不同的项目中调用和复用。

        例如,日志收集、内存监控、性能测试等功能可以分别封装成不同的 Python 模块。用户只需要根据项目需要导入相应的模块。

# uart_logger.py

import serial
import time

class UartLogger:
    def __init__(self, port='/dev/ttyUSB0', baudrate=115200, timeout=1):
        self.port = port
        self.baudrate = baudrate
        self.timeout = timeout
        self.ser = None

    def 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!")
                    break
            time.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
    }
}

# config.py
import json

def 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 time

class UartLogger:
    def __init__(self, config):
        self.port = config['uart']['port']
        self.baudrate = config['uart']['baudrate']
        self.timeout = config['uart']['timeout']
        self.ser = None

    def 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!")
                    break
            time.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_config

config = load_config('config.json')
logger = UartLogger(config)
logger.start_logging()

解释:在这个例子中,config.json 文件用来存储串口连接的相关配置。通过 load_config 函数加载配置后,UartLogger 类可以使用这些配置参数,确保脚本能够在不同的项目中灵活配置和使用。


网站公告

今日签到

点亮在社区的每一天
去签到