0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

APM32F411板的python+pyocd命令行操作

Geehy极海半导体 来源:Geehy极海半导体 2024-10-18 16:21 次阅读

1 背景

前段时间学习了一下如何使用pyocd配合APM32F411VCTINY板在命令行下给它进行各种骚操作,在使用一段时间后就想着:pyocd是基于python的,那是不是也可以使用python脚本+pyocd使用起来呢?

完成我们的一些重复的操作的自动化(因为我比较懒),嘿嘿。想到就去做。

2 pyocd 的python api

之前有介绍pyocd的时候发现遗漏了pyocd的api没有看,它还给了利用python+pyocd的一些例子(https://pyocd.io/docs/api_examples.html)。

比如下载bin文件的例子。

wKgaomcSGo6ACHfMAABgDG6E4iw831.jpg

本文档就对近段时间我学习到的pyocd+python,基于APM32F411TINY板的一些收获。由于我也是初学python,里面的一些不科学的操作,也请大家指出斧正。此致感谢!

2.1 连接

首先是连接的API:

session_with_chosen_probe()

这个api主要是控制我们选择哪个link去连接目标芯片,可以使用link的UID去指定,比如说我这里的link UID是:00350054500000144e5448590258(注:可以在CMD命令行用:pyocd list命令查看)。

wKgZoWcSGpmAR7bwAAAovmKq-LA656.jpg

那我这里设置指定使用我的 Geehy CMSIS-DAP WinUSB的设置就是:

ConnectHelper.session_with_chosen_probe(unique_id='00350054500000144e5448590258')

2.2 程序控制

让程序停下

target.halt()

让程序继续运行

target.resume()

2.3 数据读取

数据的读取指令可以使用:

target.read32(address)

这个可以读取我们MCU的flash、ram、外设寄存器等内容。

我们也可以使用指令:

target.read_core_register("pc")

读取我们程序的运行到的地方。

2.4 数据写入

数据的写入,我们可以使用:

target.write32(address,data)

这个可以对我们MCU的fram、外设寄存器等可以直接写入内容的地址进行操作。

Q:为什么不能直接对Flash进行直接写入?

A:因为flash的写入其实是flash控制器(解锁、控制、状态等寄存器),去进行的。我们通过swd的指令只能通过操作flash的控制器,从而才能对Flash进行写入。

3 程序设计

我这里设计了两个程序,对学习到的知识进行验证。

3.1 读取PE5/6的状态

这个程序我设想的是,我的APM32F411VCTINY板已经下载了一个LED闪烁的程序,我要知道LED当前的一个状态。这个其实可以类比于一个黑盒子(芯片端),我们在不开盒子的情况下去获取我们想知道的寄存器信息

程序的基本设计流程:

1. 连接APM32F411VC,

2. 读取GPIOE的ODATA寄存器,用于判断PE5/PE6的高低电平。

3. 输出寄存器内容,PE5/PE6的状态,以及相应的PC的内容。

程序如下:

import time

from pyocd.core.helpers import ConnectHelper

# Replace the following string with your target device serial number

TARGET_DEVICE_SERIAL_NUMBER = '00350054500000144e5448590258'

# APM32F411 GPIOE base address and ODATA offset

GPIOE_BASE = 0x40021000

GPIOE_ODATA_OFFSET = 0x14

# Connect to the target device with the specified serial number

with ConnectHelper.session_with_chosen_probe(unique_id=TARGET_DEVICE_SERIAL_NUMBER) as session:

# Get the target object

board = session.board

target = board.target

# ensure the target device in the running state

target.resume()

# Compute the address of the ODATA register

gpioe_odata_address = GPIOE_BASE + GPIOE_ODATA_OFFSET

# Monitor PE5 and PE6 pin status

# Monitor 10 times

for i in range(10):

target.halt()

odata = target.read32(gpioe_odata_address)

pc = target.read_core_register("pc")

target.resume()

pe5 = (odata >> 5) & 0x1

pe6 = (odata >> 6) & 0x1

# Print the contents of the odata read

print("odata: %s " % bin(odata))

print(f'PE5: {"High" if pe5 else "Low"}, PE6: {"High" if pe6 else "Low"}')

# Read some registers.

print("pc: 0x%X" % pc)

print("")

# Wait 0.5 seconds

time.sleep(0.5)

程序运行(vscode)起来得到的结果如下:

wKgZoWcSGquAfSQbAAByYNcCn20810.jpg

发现可以读取回来PE5/PE6的状态,且可以明确知道此时PC的内容。

3.2 解除/上锁APM32F411的读保护

由于我们的程序烧录进APM32F411后一般会对它进行读保护的操作,从而使得我们的程序不会被“有心人”读取**。

通过查阅APM32F411的手册,我们知道对其进行上读保护的操作的流程有:

1. 解锁选项字节编程区域;

2. 对读保护进行操作;

3. 重载选项字节。(PS:重载选项字节会引起复位,此时我们需要重新连接SWD,才能重新读取内容)

下面就根据这个流程对python脚本进行设计。

import time

from pyocd.core.helpers import ConnectHelper

# Replace the following string with your target device serial number

TARGET_DEVICE_SERIAL_NUMBER = '00350054500000144e5448590258'

# APM32F411 Option Bytes related register addresses and key values

FMC_OPTKEY = 0x40023C08

FMC_OPTCTRL = 0x40023C14

OPTCTRL_BYTE1_ADDRESS = FMC_OPTCTRL + 1 # Points to the second byte of OPTCTRL

FMC_OPT_KEY1 = 0x08192A3B

FMC_OPT_KEY2 = 0x4C5D6E7F

OB_RDP_LEVEL_1 = 0x55 # Level 1 read protection

OB_RDP_LEVEL_0 = 0xAA # No read protection

# Connect to the target MCU

with ConnectHelper.session_with_chosen_probe(unique_id=TARGET_DEVICE_SERIAL_NUMBER) as session:

target = session.board.target

# Read the current value of OPTCTRL

optctrl_value = target.read32(FMC_OPTCTRL)

rdp_level = target.read8(OPTCTRL_BYTE1_ADDRESS) # Read the second byte directly

if rdp_level != OB_RDP_LEVEL_0:

print("Target MCU is already read protected")

else:

print("Target MCU is not read protected, proceeding with read protect operation...")

# Unlock Option Bytes programming

if optctrl_value & (1 << 0):  # Check the OPTLOCK bit

target.write32(FMC_OPTKEY, FMC_OPT_KEY1)

target.write32(FMC_OPTKEY, FMC_OPT_KEY2)

optctrl_value = target.read32(FMC_OPTCTRL)

print("optctrl_value: 0x%X" % optctrl_value)

# Set the read protection level (only modify the second byte)

target.write8(OPTCTRL_BYTE1_ADDRESS, OB_RDP_LEVEL_1)

# Start the Option Bytes programming

optctrl_value = target.read32(FMC_OPTCTRL)

optctrl_value |= (1 << 1)  # Set the OPTSTRT bit

print("optctrl_value: 0x%X" % optctrl_value)

target.write32(FMC_OPTCTRL, optctrl_value)

# Wait for programming to complete and trigger a reset

while True:

optctrl_value = target.read32(FMC_OPTCTRL)

if not (optctrl_value & (1 << 1)):  # Wait for the OPTSTRT bit to be cleared

break

# Perform a hardware reset of the target MCU

session.probe.reset()

# Wait 0.5 seconds

time.sleep(0.5)

# Re-establish the connection after the reset

with ConnectHelper.session_with_chosen_probe(unique_id=TARGET_DEVICE_SERIAL_NUMBER) as new_session:

new_target = new_session.board.target

# Verify if read protection has been successfully set

new_optctrl_value = new_target.read32(FMC_OPTCTRL)

new_rdp_level = (new_optctrl_value >> 8) & 0xFF

if new_rdp_level == OB_RDP_LEVEL_1:

print("Read protect operation successful")

else:

print("Read protect operation failed")

脚本运行结果如下:

wKgZoWcSGryAG-j5AACFnI2d_IQ977.jpg

当然我也给大家准备了解锁的操作的脚本,脚本运行结果如下:

wKgaoWcSGseAQAfYAAB1Sp8JObI517.jpg

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • python
    +关注

    关注

    56

    文章

    4782

    浏览量

    84449
  • 命令行
    +关注

    关注

    0

    文章

    77

    浏览量

    10380
  • 脚本
    +关注

    关注

    1

    文章

    387

    浏览量

    14830

原文标题:APM32芯得 EP.34 | 还可以这样玩?APM32F411与pyocd的火花

文章出处:【微信号:geehysemi,微信公众号:Geehy极海半导体】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    玩转SQLite2:SQLite命令行基本操作

    本篇介绍SQLite的命令行基本操作
    的头像 发表于 09-23 08:59 2174次阅读
    玩转SQLite2:SQLite<b class='flag-5'>命令行</b>基本<b class='flag-5'>操作</b>

    TinyMaix框架的内存需求超过了APM32F411的可用内存,导致运行失败,怎么能成功优化?

    TinyMaix框架的内存需求超过了APM32F411的可用内存,导致运行失败。怎么能成功优化?
    发表于 09-27 09:44

    cmd网络经典命令行

    cmd网络经典命令行:
    发表于 06-11 15:17 36次下载
    cmd网络经典<b class='flag-5'>命令行</b>

    caxa命令行中的应用

    caxa命令行中的应用 命令行对于大多用户来说往往只是输入数据的作用,但是其中的奥妙还有很多,下面就给大家
    发表于 10-18 18:18 2280次阅读

    博达环网配置命令行

    博达工业交换要环网配置命令行
    发表于 12-27 16:24 0次下载

    CMD的命令行高级教程

    CMD的命令行高级教程
    发表于 10-24 08:31 30次下载
    CMD的<b class='flag-5'>命令行</b>高级教程

    Linux命令行与shell脚本编写

    Linux命令行与shell脚本编写
    发表于 01-11 16:50 4次下载

    如何在Linux命令行中运行Python脚本

    Python 是一种高级编程语言,被广泛应用于数据科学、机器学习、Web 开发等领域。在 Linux 操作系统中,Python 是一个默认安装的解释器,用户可以通过命令行界面(CLI)
    的头像 发表于 05-12 14:49 1660次阅读

    linux命令行与shell编程实战

    Linux命令行与Shell编程实战主要涉及以下内容: Linux命令行基础:学习Linux命令行的基本操作,如文件管理、进程管理、网络配置等。熟悉使用
    的头像 发表于 11-08 10:57 734次阅读

    linux虚拟机怎么调出命令行

    快捷键组合Ctrl+Alt+F1 6来切换到命令行界面。如果系统在虚拟机中,则可以使用Ctrl+Alt+shift+F1 6组合键来切换到命令行界面。在
    的头像 发表于 11-08 11:28 2999次阅读

    linux切换到命令行模式

    在Linux中,可以通过以下步骤切换到命令行模式: 打开终端。可以在应用菜单中找到终端或命令行终端。 在终端中输入命令“exit”或“logout”,然后按回车键。 系统会提示您输入管理员密码。输入
    的头像 发表于 11-13 16:47 1719次阅读

    linux虚拟机命令行界面如何操作

    Linux虚拟机的命令行界面可以分为四个方面进行详尽的说明:登录、基本操作、文件管理和系统管理。 第一部分:登录 首先,您需要启动虚拟机并打开终端。在启动过程中,您可以按下一些键(如F12、Del或ESC,具体取决于虚拟化软件)
    的头像 发表于 11-17 09:57 1656次阅读

    pycharm命令行终端运行代码

    Python是一种非常流行的编程语言,许多开发者使用它来编写各种应用程序和脚本。为了方便开发者编写和测试代码,PyCharm是一种集成开发环境(IDE),它提供了许多功能和工具,其中包括命令行终端
    的头像 发表于 11-22 11:20 4616次阅读

    eclipse怎么使用命令行

    命令行中使用Eclipse来完成一些特定的任务。本文将详细介绍如何在命令行中使用Eclipse。 首先,我们需要确保已经正确安装了JDK(Java Development Kit)和Eclipse
    的头像 发表于 12-06 11:26 2429次阅读

    idea如何输入命令行参数

    在许多软件开发和系统管理的任务中,我们经常需要向应用程序传递命令行参数。命令行参数是在运行时传递给程序的值,用于指定程序的行为和配置选项。本文将详细介绍如何在不同的编程语言和操作系统中输入命令
    的头像 发表于 12-06 15:01 1077次阅读