在没有 R/W 保护的情况下闪烁代码后 STM32 闪烁禁用

Posted

技术标签:

【中文标题】在没有 R/W 保护的情况下闪烁代码后 STM32 闪烁禁用【英文标题】:STM32 flashing disabled after flashing a code without R/W protection 【发布时间】:2015-08-30 01:03:02 【问题描述】:

我有一些使用 StdPeriph 库来编程 stm32 的经验。但现在我用 STM32CubeMX 代码生成器尝试了 STM32Cube HAL。我用这个选项生成了一个项目:

中间件:通过 SDIO 的 FreeRTOS 和 FatFS 编译器为 GCC stm32f103ret6 MCU

我将生成的代码导入 Eclipse 环境。我制作了一个二进制文件,并像往常一样用“st-flash write ...”将其刷新。我的测试程序成功地循环写入 USART1 “Hello” - 这没问题。但是,当我尝试刷新另一个代码时,它以“未知芯片 ID”失败。如果我手动将 NRST 连接到 GND,st-flash 会给出:

...Flash: 0 bytes (0 KiB) in pages of 2048 bytes

完整输出:

2015-06-14T16:07:29 INFO src/stlink-common.c: Loading device parameters....
2015-06-14T16:07:29 INFO src/stlink-common.c: Device connected is: F1 High-density device, id 0x10036414
2015-06-14T16:07:29 INFO src/stlink-common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0 bytes (0 KiB) in pages of 2048 bytes

我尝试在 Windows 中使用 ST-Link Utility,但它无法连接到此 MCU 来更改选项字节(使用 stm32 连接到其他设备效果很好)。 我尝试刷过 USART1,但失败了。

我刷的源代码当然不包含任何读/写保护启用。我又试了2个单片机,还是重现了这个错误。

如何通过 MCU 拆砖并刷写任何东西?

【问题讨论】:

一些 MCU 包含电路(闪存上的一个或多个特定位)以防止对闪存内容的未经授权的访问。当启用安全性(这些位设置为特定值)时,闪存被视为安全资源,不能再重新编程。您应该向您最喜欢的神或女神祈祷,您所处的情况并非如此。达到这种情况的另一种方法是设置闪存保护寄存器,该寄存器也映射到某个闪存地址。您应该能够通过重新编程此闪存地址来从这种情况中恢复。 我知道您写了“没有 R/W 保护”,但即使您的代码没有明确设置启用 R/W 保护,您可能在尝试对代码进行编程时将其直接编程到闪存中(进错地址什么的)。 如果仍然设置了 R/W 保护,我应该可以通过 Windows 中的 ST-Link 实用程序将其删除,不是吗?但我什至无法连接到我的设备... 大约两周前遇到了完全相同的问题(尽管在不同的 MCU 上)。原因是我们写入了 Flash-Secure 字节(准确地说是 2 位)。现在,如果您的已编程应用程序部署了此安全功能附带的后门机制,则可以撤消它。否则,将无法再通过 JTAG(或任何其他方式)访问 MCU。换句话说,这里必须避免使用,检查 Con Air(电影)并搜索 Pinball 的引语,以“我不知道如何告诉你,赛勒斯......”开头。 但为了消除所有疑虑,我建议您参考 STM32 数据表,看看这个 MCU 上是否存在安全功能。搜索 Flash Security 或类似内容... 【参考方案1】:

它(BURIED)在 Pinout 下 |系统 | STM32CubeMX 的调试...设置为串行线或其他。

【讨论】:

【参考方案2】:

如果您在 STM32CubeMX 的 pinout 选项卡上正确设置 JTAG/SWD 引脚的引脚分配(例如 SYS_JTDI、SYS_JTDO-TRACESWO 等),生成的代码将不会禁用 JTAG/SWD。​​p>

【讨论】:

快捷方式:在Peripherals/SYS/Debug下,您可以选择您将使用的接口类型,它会设置正确的引脚分配。【参考方案3】:

我找到了根本原因!

这是一个HAL初始化函数,由STM32CubeMX生成:

void HAL_MspInit(void)

  /* USER CODE BEGIN MspInit 0 */

  /* USER CODE END MspInit 0 */

  __HAL_RCC_AFIO_CLK_ENABLE();

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

  /* System interrupt init*/
/* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

    /**DISABLE: JTAG-DP Disabled and SW-DP Disabled 
    */
  __HAL_AFIO_REMAP_SWJ_DISABLE();

  /* USER CODE BEGIN MspInit 1 */

  /* USER CODE END MspInit 1 */

我没有注意到这些简单的线条!

/**DISABLE: JTAG-DP Disabled and SW-DP Disabled 
*/
__HAL_AFIO_REMAP_SWJ_DISABLE();

此宏完全禁用 SWD 和 JTAG 编程,请查看 stm321xx_hal_gpio_ex.h

#define __HAL_AFIO_REMAP_SWJ_DISABLE()  MODIFY_REG(AFIO->MAPR, AFIO_MAPR_SWJ_CFG, AFIO_MAPR_SWJ_CFG_DISABLE) 

我没有在 CubeMX 中找到任何用于禁用/启用 SWD/JTAG 的复选框,所以这是代码生成器的唯一行为!使用STM32CubeMX时要注意这一点!

【讨论】:

检查外设树下的 SYS 项目并设置 Debug -> Serial-Wire (default - disabled)

以上是关于在没有 R/W 保护的情况下闪烁代码后 STM32 闪烁禁用的主要内容,如果未能解决你的问题,请参考以下文章

按下按钮时从 STM32 ADC 获取读数

STM32F4程序只有在按下复位按钮后才会运行

STM32 重置问题

STM32F103C8T6基于Arduino框架下利用定时器跑RBG灯闪烁

STM32 通过引导加载程序闪烁失败 (UART1)

SDRAM 与 STM32F429BI 接口存在闪烁问题