PyOCD部分源码解析

PyOCD部分源码解析

1. 探测下载器流程

检测下载器部分代码:

ConnectHelper.list_connected_probes()
allProbes = ConnectHelper.get_all_connected_probes(blocking=False)
allProbes = DebugProbeAggregator.get_all_connected_probes(unique_id=unique_id)

使用静态方法进行探测,probe目录下实现了几种常见的调试器,如CMSIS DAP、Jlink等,采用插件加载的方式加载这些probe的子类,这些子类统一继承自DebugProbe。

cmsis_dap_probe.py内的get_all_connected_probes方法描述了如何发现dap设备。

cmsis_access_cmsis_dap.py中的DAPAccessCMSISDAP是具体实现细节,DAPAccess.get_connected_devices(),在此方法中调用两个接口,一个是CMSIS-DAPv1 interfaces,另一个是CMSIS-DAPv2 interfaces
board.py中根据target_override参数来实例化target:

# Convert dashes to underscores in the target type, and convert to lower case.
target = normalise_target_type_name(target)
self._target_type = target
self.target = TARGET[self._target_type](session)#实例化

2.硬件相关

插入CMSIS DAP,使用pyocd list命令能够获取到设备信息:

(base) C:\Users\Administrator>pyocd list
  #   Probe/Board                                   Unique ID      Target
---------------------------------------------------------------------------
  0   CMSIS-DAP by muselab-tech.com JCK CMSIS-DAP   0001A0000001   n/a

在设备管理器中可以看到设备类型和VID&PID:

在这里插入图片描述

3.loader子命令执行流程

(1)调用load_cmd.py中invoke方法
(2)ConnectHelper.session_with_chosen_probe方法获取session,该方法如下:

# Choose a probe.
probe = ConnectHelper.choose_probe(
    blocking=blocking,
    return_first=return_first,
    unique_id=unique_id,
)
if probe is None:
    return None
else:
    return Session(probe, auto_open=auto_open, options=options, **kwargs)

choose_probe方法调用流程如下:
● 首先获取所有已连接的设备ConnectHelper.get_all_connected_probes(blocking=blocking, unique_id=unique_id);
● DebugProbeAggregator通过PROBE_CLASSES存储所有类型的下载器,如CMSIS-DAP等,通过load_plugin_classes_of_type(‘pyocd.probe’, PROBE_CLASSES, DebugProbe)方法扫描并注册基类为DebugProbe的类,load_plugin_classes_of_type返回所有继承自DebugProbe的类并添加到PROBE_CLASSES字典;
● pydapaccess.py中的get_connected_devices()方法获取已经连接的设备
● 调用dap_access_cmsis_dap.py中的get_connected_devices方法
● 通过调用_get_interfaces方法获取连接设备
● 分别通过v1_interfaces(USB_BACKEND)和v2_interfaces(USB_BACKEND_V2)来执行get_all_connected_interfaces
● interface目录下包含各种版本的DAP接口,可以通过环境变量来控制使用何种版本的接口,如果环境变量不指定,USB_BACKEND那么根据操作系统版本进行不同的操作,windows系统如果HidApiUSB.isAvailable,就优先使用HidApi,否则使用PyWinUSB.isAvailable就使用WinUSB,如果是MacOS则使用hidapiusb,如果是Linux则使用pyusb。
● USB_BACKEND_V2使用pyusb_v2
● 默认windows使用hidapi_backend.py
Session中board包含target的信息。

4.擦除流程

(1)ConnectHelper.session_with_chosen_probe获取session,session中的target为CoreSightTarget
(2)创建FlashEraser
(3)执行erase方法,该方法传递一个地址参数address,默认此处跟的是整片擦除,所以_mode为Mode.CHIP
(4)调用_chip_erase()方法
(5)执行以下代码:

if self._log_chip_erase:
            LOG.info("Erasing chip...")
        # Erase all flash regions. This may be overkill if either each region's algo erases
        # all regions on the chip. But there's no current way to know whether this will happen,
        # so prefer to be certain.
        for region in self._session.target.memory_map.iter_matching_regions(type=MemoryType.FLASH):
            if region.flash is not None:
                if region.flash.is_erase_all_supported:
                    region.flash.init(region.flash.Operation.ERASE)
                    region.flash.erase_all()
                    region.flash.cleanup()
                else:
                    self._sector_erase([(region.start, region.end)])
        if self._log_chip_erase:
                LOG.info("Chip erase complete")

首先在memory_map中查询类型为MemoryType.FLASH的区域,遍历所有region,如果支持整片擦除则调用整片擦除方法,否则使用sector擦除方法。

总结

本文仅揭示了PyOCD实现的冰山一角,建议读者通过以下路径深入探索:

  1. 研究pyocd.gdbserver模块的调试服务实现
  2. 分析CMSIS-Pack设备支持包的加载机制
  3. 跟踪SWD协议数据包在pyocd.coresight中的处理流程
  4. 实践自定义调试器驱动的开发

PyOCD通过清晰的模块划分和抽象层次设计,既保证了跨平台兼容性,又为二次开发提供了良好基础。理解其源码结构,有助于开发者针对特定需求进行深度定制和功能扩展。

### PyOCD 使用指南 #### 工具简介 PyOCD 是一个开源的调试工具,支持多种 ARM Cortex-M 微控制器。它提供了丰富的功能集,包括目标设备的调试、闪存编程以及实时数据监控等功能。 #### 下载与安装 为了获取最新的稳定版本 PyOCD,可以通过 `pip` 命令完成安装过程[^2]: ```bash pip install -U pyocd ``` 如果需要从源码构建,则可访问其官方仓库下载代码并手动编译[^1]: ```bash git clone https://gitcode.com/gh_mirrors/pyo/pyOCD.git cd pyOCD pip install . ``` #### 配置文件说明 PyOCD 的配置主要依赖于 JSON 文件或者命令行参数设置。这些配置项用于定义连接的目标硬件、使用的协议(SWD/JTAG)、波特率以及其他高级选项等[^3]。例如,在默认情况下会尝试自动检测探针;但如果存在多个探针时,可能需要显式指定 ID。 #### 初次运行测试 安装完成后可通过简单的命令验证是否成功部署了 PyOCD 及其关联组件。以下是基本的操作演示: - **列出可用调试适配器** ```bash pyocd list ``` - **查看当前连接的目标信息** ```bash pyocd json --probe <PROBE_ID> ``` 其中 `<PROBE_ID>` 替换为你实际环境中探测到的具体编号。 #### 结合其他软件生态使用 对于某些特定场景下还需要额外准备一些前置条件。比如当涉及 USB 设备交互时,建议先按照指导手册准备好 LibUSB 支持环境[^4]。而对于嵌入式开发人员来说,集成至 RT-Thread Studio 这样的 IDE 中能够极大提升工作效率[^5]。 --- ### 示例:简单 flash 编程脚本 下面给出一段基于 Python 调用 PyOCD API 实现自动化烧录固件的小例子。 ```python from pyocd.core.session import SessionOptions import pyocd.flash.file_programmer as fp def program_firmware(binary_path, target_name="auto"): options = SessionOptions() with pyocd.tool_session.Session(options=options) as session: programmer = fp.FileProgrammer(session) programmer.program(binary_path) if __name__ == "__main__": binary_file = "./example.bin" program_firmware(binary_file) ``` 此片段展示了如何通过调用 FileProgrammer 类方法向目标 MCU 加载二进制镜像文件。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值