打印
[STM32G0]

实战经验 | STM32G0执行I2C bootloader Go命令后无法连接问题解析

[复制链接]
107|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 STM新闻官 于 2024-6-11 13:51 编辑

01引言
在 STM32G0B1 的 FLASH_ACR 寄存器中有个 DBG_SWEN 位,当这个位的值为 0 时,设备就禁用调试能力,无法通过调试器连接到设备,反之则启用调试能力。下图是参考手册中的相关描述:
▲ 图1. RM0444_rev5 的 3.7.1 章节
从上图中可以看出,FLASH_ACR 寄存器的默认值为 0x00040600,即 DBG_SWEN 位的默认值为 1,也就是默认情况下是允许调试访问设备的。

0
2问题描述
客户使用的是 STM32G0B1 的 I2C bootloader,bootloader 版本是 0x92,在执行完"Go"命令后使用 STM32CubeProgrammer 在"hot plug"模式下连接设备,但是连接失败,提示无法找到设备。
03问题复现与分析
使用 NUCLEO-G0B1RE 板进行测试,bootloader 版本与客户的一致都是 0x92,通过配置选项字节将设备配置为从 system memoery 自举(也就是复位后进入片内 bootloader 中执行)。下图是 STM32G0B1 的参考手册中关于 boot modes 的描述,如下图所示 :
▲ 图2. RM0444_rev5 的 2.5 章节
如上图所示,在 boot modes 中显示有两种配置可从 system memory 自举,这里我使用的配置是"nBOOT1=0x1, nBOOT_SEL=0x1, nBOOT0=0x0",下图是通过 CubeProgrammer 配置选项字节的结果:
▲ 图3. 选项字节配置

配置完从 system memory 自举之后,我们可以看到"PC"指向 0x1FFFxxxx 的地址,这里就说明 MCU 已经在 bootloader 中运行了。
▲ 图4. 配置完选项字节后的 PC 值

然后将应用程序下载到设备中(我这里下载到 0x08000000 地址处),这一步主要是保证执行"Go"命令时可以跳转到可以运行的程序中。最后通过 I2C bootloader 引脚与 bootloader 主机端连接,然后执行"Go"命令。下图是 I2C bootloader 的"Go"命令在 host 端的流程图:
▲ 图5. AN4221_rev12 Go command: host side

下图是用逻辑分析仪抓取的"Go"命令的执行流程,跳转的地址是 0x08000000,可以 看出执行流程与文档中描述的一致,"Go"命令执行成功。
▲ 图6. 逻辑分析仪抓取到的 Go 命令执行流程

"Go"命令执行成功后,接着使用 CubeProgrammer 通过 SWD 接口连接设备。在测 试时发现,在"hot plug"模式时连接失败,但是在"normal"模式并且复位模式为 "Hardware reset"时可以连接成功,但是在非"hardware reset"时不能连接成功。
▲ 图7. 连接失败时的 log

下面是几种连接方式的说明:
▲ 图8. UM2237_Rev23 的 2.1.4 章节

从上图中的介绍我们可以看出,"hot-plug"模式在连接时不进行复位,而在 normal 模式会进行复位,并且复位方式可以自由选择。而"Software reset"和"Core reset"都需要通设置设备的寄存器进行复位,所以首先需要通过调试接口连接到设备进而才能操作设备的寄存器,而"Hardware reset"则不需要,因为它是通过 nRST 引脚进行的复位。

也就是说,测试结果显示,在执行完 "Go"命令后只有执行了硬件复位后才能通过调试 接口成功连接到设备。而在硬件复位后,设备会根据 boot modes 的配置选择自举地址, 这里的 boot modes 配置的是从 system meomry 中自举(片内 bootloader 就在 system memory 中),所以在复位后设备还是进入了 bootloader 中。也就是只有在执 行"Go"命令之后,才会出现不能通过调试接口连接到设备的情况,复位后重新回到 bootloader 后是可以的。从“前言”中的描述中我们可以知道 DBG_SWEN 的默认值为 1,所以很可能是在通 过 I2C bootloader 执行完"Go"命令后,设备的 FLASH_ACR 寄存器的 DBG_SWEN 位被 设置为 0 了,所以我们无法通过调试器进行连接。

04验证
4.1. 查看执行完 I2C bootloader 的"Go"命令后的 DBG_SWEN 的状态
在下载到设备的应用程序中添加打印 FLASH_ACR 寄存器的 DBG_SWEN 位的操作, 用来查看执行完 I2C bootloader 的"Go"命令后的 DBG_SWEN 的状态。
然后将程序下载到设备中,如果我们设置的 boot modes 从 main flash 中启动的话,我们可以看到 DBG_SWEN 位的值为 1,此时是可以通过调试接口连接到设备的。如下图所示:
▲ 图9. 从 main flash 中启动时的测试结果

如果是从 bootloader 启动,然后通过 I2C bootloader 的"Go"命令跳转到应用程序中执行的话。可以看到 DBG_SWEN 位的值为 0,在复位之前无法通过调试器连接到设备,也就是出现问题时的现象。如下图所示:
▲ 图10. 通过 I2C bootloader 的"Go"命令跳转到应用程序中执行的结果

所以从这里可以看出,执行完 I2C bootloader 的"Go"命令后,DBG_SWEN 位被设置 为 0,所以此时我们无法通过调试器连接到设备。但是这个位的默认值为 1,所以我们可 以通过复位来恢复其默认值,或者通过软件进行设置都可以将其设置为 1。

4.2. 通过软件将 DBG_SWEN 置位
HAL_FLASHEx_EnableDebugger()是 HAL 库中提供的将 DBG_SWEN 置位的函数, 下面是添加的代码。
将固件下载到设备中,并且从 bootloader 启动,然后通过 I2C bootloader 的"Go"命 令跳转到应用程序中执行。可以看到刚开始时 DBG_SWEN 位为 0,然后将 DBG_SWEN位置位,通过回读 DBG_SWEN 位的结果可以看到已经成功置位了 DBG_DWEN,此时再 通过"hot plug"模式就可以连接到设备。下面是测试结果:

▲ 图11. 测试结果

通过上面两个测试我们可以看出,在 STM32G0B1x 的 0x92 版本的片内 bootloader 中,如果通过 I2C 接口执行"Go"命令跳转到应用程序时,DBG_SWEN 位将会被清零,此 时也就无法通过调试器连接到设备。如果想要恢复设备的调试能力的话,需要在应用程序 添加设置 DBG_SWEN 位为 1 的操作或者进行复位。

05小结
在 STM32G0B1x 的 0x92 版本的 bootloader 中,通过 I2C 接口执行完"Go"命令跳转 到应用程序时,会将设备的 DBG_SWEN 位配置为 0,也就是禁用设备的调试能力。如果 我们想要恢复调试能力的话,可以在应用程序中添加设置 DBG_SWEN 位为 1 的操作。但 是其它型号或者其它版本的 bootloader 执行"Go"命令后,不一定会有这种设置,我们应 该具体应用具体分析,详细可以参考 AN2606,AN2606 是 STM32 bootloader 的说明 文档。

▼▼▼

使用特权

评论回复
沙发
classroom| | 2024-6-11 16:23 | 只看该作者
挺不错的实战经验,支持一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:意法半导体(中国)投资有限公司
简介:您的嵌入式应用将得益于意法半导体领先的产品架构、技术、多源产地和全方位支持。意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。

510

主题

644

帖子

17

粉丝