在STM32H7上从RDP级别1回归到0

在STM32H7上从RDP级别1回归到0,stm32,flash-memory,Stm32,Flash Memory,我在玩STM32H743(核子板,STM32CubeIDE)上的RDP级别 以下是我测试过的代码: int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART3_UART_Init(); OBInit.Banks = FLASH_BANK_1; HAL_FLASHEx_OBGetConfig(&OBInit); RdpLevel = OBInit.RDPLev

我在玩STM32H743(核子板,STM32CubeIDE)上的RDP级别

以下是我测试过的代码:

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART3_UART_Init();

  OBInit.Banks     = FLASH_BANK_1;
  HAL_FLASHEx_OBGetConfig(&OBInit);
  RdpLevel = OBInit.RDPLevel;

  BSP_PB_Init(BUTTON_USER,BUTTON_MODE_GPIO);
  BSP_LED_Init(LED1);

  if ( RdpLevel == OB_RDP_LEVEL_0 )
  {
    // toggle LED1 to show RDP level
    BSP_LED_Toggle(LED1);

    /* Wait for User push-button press before starting the Communication */
    while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_SET);

    // program OB
    HAL_FLASH_OB_Unlock();
    HAL_FLASH_Unlock();

    OBInit.OptionType = OPTIONBYTE_RDP;
    OBInit.RDPLevel   = OB_RDP_LEVEL_1;
    HAL_FLASHEx_OBProgram(&OBInit);

    /* Start the Option Bytes programming process */
    if (HAL_FLASH_OB_Launch() != HAL_OK)
    {
        /* User can add here some code to deal with this error */
        while (1)
        {
            BSP_LED_Toggle(LED1);
            HAL_Delay(200);
        }
    }

  }
  else
  {
        BSP_LED_Toggle(LED2);

      /* Wait for User push-button press before starting the Communication */
        while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_SET);


        // program OB
        HAL_FLASH_OB_Unlock();
        HAL_FLASH_Unlock();

        OBInit.OptionType = OPTIONBYTE_RDP;
        OBInit.RDPLevel   = OB_RDP_LEVEL_0;
        HAL_FLASHEx_OBProgram(&OBInit);

        /* Start the Option Bytes programming process */
        if (HAL_FLASH_OB_Launch() != HAL_OK)
        {
            /* User can add here some code to deal with this error */
            while (1)
            {
                BSP_LED_Toggle(LED2);
                HAL_Delay(200);
            }
        }
  }
  while (1)
  {
  }
}
切换到1级工作正常。我看到该级别已被考虑在内(在下次重置时,调试器不再工作)。LED还显示液位

但当我尝试返回到0级时,我不确定发生了什么,因为我无法调试:我知道闪存会完全擦除。但是我希望在那之后我能够通过调试器连接。但事实并非如此,该软件似乎不再运行

这段代码有什么错误吗


编辑:我尝试在回归后关闭电路板电源

答案非常简单,并在STM32文档中进行了解释。当您将RDP从级别1更改为级别0时,需要上电重置。因此,您需要断开电源,然后重新连接。

答案非常简单,并在STM32文档中进行了解释。当您将RDP从级别1更改为级别0时,需要上电重置。因此,您需要断开电源,然后重新连接。

显然,这是由于勘误表“选项字节加载可以通过用户等待状态配置完成”中描述的错误造成的。我将软件中的等待状态编号从4改为7,解决了这个问题。我可以毫无问题地切换回0级。

显然,这是由于勘误表“选项字节加载可以通过用户等待状态配置完成”中描述的错误造成的。我将软件中的等待状态编号从4改为7,解决了这个问题。我可以毫无问题地切换回0级。

我知道这是一篇较旧的帖子,但。。。过去我在这方面花了不少时间。如果您将RDP正确设置为0级,CPU将擦除所有闪存,将RDP级清除为0,然后自行复位。但是,如果连接了ST Link之类的调试器,它将擦除闪存,将RDP设置为零级,然后CPU将挂起。需要手动复位/电源循环。这记录在参考手册中的某个地方。因此,带有自动重置功能的RDP过程在没有附加调试器的生产代码中运行良好,我们每天都使用它。

我知道这是一篇较旧的帖子,但。。。过去我在这方面花了不少时间。如果您将RDP正确设置为0级,CPU将擦除所有闪存,将RDP级清除为0,然后自行复位。但是,如果连接了ST Link之类的调试器,它将擦除闪存,将RDP设置为零级,然后CPU将挂起。需要手动复位/电源循环。这记录在参考手册中的某个地方。因此,带有自动重置的RDP过程在没有附加调试器的生产代码中运行良好,我们每天都使用它。

是的,我忘记了精确,但我也这样做了。因此,现在您可以尝试连接st link实用程序。也许它可以删除保护是的,我知道怎么做(更改引导地址并使用ST USB引导加载程序)。但是它没有修复我的代码。不-没有引导加载程序只有通过SWD的stlink实用程序。这是一个非常新鲜的加州大学,我会非常小心地与哈尔图书馆,知道过去。两年后,STM将纠正最重要的错误:)。现在使用裸寄存器进行操作。是的,我同意HAL,但我在寄存器级别一步一步地检查,没有发现任何错误。是的,我忘了精确,但我也这样做了。因此,现在您可以尝试连接st link实用程序。也许它可以删除保护是的,我知道怎么做(更改引导地址并使用ST USB引导加载程序)。但是它没有修复我的代码。不-没有引导加载程序只有通过SWD的stlink实用程序。这是一个非常新鲜的加州大学,我会非常小心地与哈尔图书馆,知道过去。两年后,STM将纠正最重要的错误:)。现在使用裸寄存器进行操作。是的,我同意HAL,但我在寄存器级别一步一步地检查,没有发现任何错误。断开电路板的电源还必须包括断开任何通信电缆,如SWD或串行调试,这些电缆可以注入足够的电流,以保持处理器状态部分处于活动状态。此外,您应该让代码读回更改的值并打印出来,很可能您没有完成更改的所有步骤,例如,通常需要写入值及其补码,不清楚您尝试使用的库函数是否为您完成了所有这些操作。还可以尝试使用调试器及其软件更改保护值并触发批量擦除。之后,您仍需要在断开所有电缆的情况下重新通电,然后,重新连接后,您应该返回-至少除非您完成了永久性更改。断开电路板电源还必须包括断开任何通信电缆,如SWD或串行调试,这可能会注入足够的电流,以保持处理器状态部分处于活动状态。此外,您应该让代码读回更改的值并打印出来,很可能您没有完成更改的所有步骤,例如,通常需要写入值及其补码,不清楚您尝试使用的库函数是否为您完成了所有这些操作。还可以尝试使用调试器及其软件更改保护值并触发批量擦除。您仍然需要在所有电缆断开后重新通电,然后在重新连接后,您应该重新连接-至少,除非您完成了永久性更改。正如我在“自我回答”中解释的,这显然是由于STM32H7闪存等待状态的一个非常具体的问题。我在手动关机。很明显,你是对的,用调试器做这类事情有点粗略,正如我在“回答我自己”中解释的,这显然是因为STM32H7上的闪存等待状态有一个非常具体的问题。我在手动关机。很明显你这么做是对的