闪存操作后无法对STM32进行编程

问题描述 投票:0回答:1

我正在开发一个项目,涉及使用 STMCubeIDE 向 STM32F042x 微控制器闪存读取和写入数据

手册规定闪存大小为32KBytes,从地址

0x08000000
开始:

但是,自动生成的链接描述文件仅允许 16k 字节的内存,从

0x08000000
开始。

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 6K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 16K
}

因此,我认为地址

0x08004000
(据说是第一个未使用的地址)是放置我的数据的理想位置。我创建了一个程序来测试这是否有效,该程序基本上以无限循环的方式读取和写入上述闪存地址,每次延迟 100 毫秒。不幸的是,我没有将延迟放在正确的位置,并且它目前运行没有任何延迟。该程序位于问题的末尾。 在调试模式下运行程序并检查确实使用内存浏览器在正确的地址操作了闪存后,我无法再对我的 STM 进行编程,因为未检测到微控制器(但 ST Link 工作正常) ).

经过一点研究,我认为唯一可能的问题是:

  • STlink 在该闪存地址处有一些重要的电路板识别信息
  • 程序循环写入Flash存储器,如果阻止编程器读写Flash存储器,就会导致失败

然而,这可能是我没有想到的完全不同的事情。此时我对如何再次对 STM32 进行编程一无所知,所以任何帮助将不胜感激。谢谢你。

导致问题的程序:

void Flash_Read_Data (uint32_t StartPageAddress, uint32_t *RxBuf, uint16_t numberofwords) {
        while (1) {
            *RxBuf = *(__IO uint32_t *)StartPageAddress;
            StartPageAddress += 4;
            RxBuf++;
            if (!(numberofwords--)) break;
         }
    }
    
    
    uint32_t Flash_Write_Data (uint32_t StartPageAddress, uint32_t *Data, uint16_t numberofwords) {
        static FLASH_EraseInitTypeDef EraseInitStruct;
        uint32_t PAGEError;
        int sofar=0;
          /* Unlock the Flash to enable the flash control register access *************/
           HAL_FLASH_Unlock();
           /* Erase the user Flash area*/
          uint32_t StartPage = GetPage(StartPageAddress);
          uint32_t EndPageAdress = StartPageAddress + numberofwords*4;
          uint32_t EndPage = GetPage(EndPageAdress);
           /* Fill EraseInit structure*/
           EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
           EraseInitStruct.PageAddress = StartPageAddress;
           EraseInitStruct.NbPages     = ((EndPageAdress - StartPageAddress)/FLASH_PAGE_SIZE) +1;
           if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
             /*Error occurred while page erase.*/
              return HAL_FLASH_GetError ();
           }
           /* Program the user Flash area word by word*/
           while (sofar<numberofwords) {
             if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, StartPageAddress, Data[sofar]) == HAL_OK) {
                 StartPageAddress += 4;  // use StartPageAddress += 2 for half word and 8 for double word
                 sofar++;
             }
             else {
               /* Error occurred while writing data in Flash memory*/
                 return HAL_FLASH_GetError ();
             }
           }
           /* Lock the Flash to disable the flash control register access (recommended
              to protect the FLASH memory against possible unwanted operation) *********/
           HAL_FLASH_Lock();
           return 0;
      }
    
    int main(void) {
      uint32_t read_data[16];
      uint32_t write_data[2] =  {33,44};
      while (1)
      {
          Flash_Read_Data(0x8004000,read_data,1);
          Flash_Write_Data(0x8004000,write_data,2);
          Flash_Read_Data(0x8004000,read_data,1);
      }
      HAL_Delay(100); /* Delay doesn't work as it is outside the infinite loop */
    }
c linker stm32
1个回答
0
投票
  1. Flash 编程与 gdbServer 的 uC 检测无关。
  2. 如果你有便宜的中国 ST-Link 克隆,那么恢复会有点复杂(请参阅第 4 页)。
  3. 如果您有正版,则需要重置下连接。它将解锁您的 uC
  4. 由于廉价的 ChPR ST-Link 克隆不会暴露复位线,当 ST-Link 尝试连接到芯片时,您必须手动将其 NRST 引脚连接到 GND(我建议使用 200 欧姆电阻)。您可能需要多次执行此操作才能成功。
© www.soinside.com 2019 - 2024. All rights reserved.