stm32f746 флэш-чтение после записи возвращает ноль - PullRequest
0 голосов
/ 28 августа 2018

Я сохраняю настройки во флэш-памяти и читаю их снова. 2 значения всегда возвращаются пустыми. Однако данные записываются на флэш-память, поскольку после сброса считанные значения являются новыми сохраненными значениями, а не пустыми.

Я начал испытывать эту проблему после некоторого рефакторинга кода после передачи кода из другой компании.

Сохранение и чтение настроек обратно работает, когда вы действительно делаете следующее (старый неэффективный способ): сохранить настройку 0 - прочитать настройку 0 сохранить настройку 1 - прочитать настройку 1 ... сохранить настройку 13 прочитать настройку 13

Это КРАЙНЕ неэффективно и медленно, поскольку та же страница со всеми настройками считывается из флэш-памяти, очищается весь блок флэш-памяти, новые настройки помещаются в буфер чтения, а затем весь блок (только с 1 измененной настройкой) записано во флеш. И это происходит для всех 14 настроек! Но это работает ...

unsigned char Save_One_Setting(unsigned char Setting_Number, unsigned char* value, unsigned char length)
{
  /* Program the user Flash area word by word
    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
  unsigned int a;

  Address = FLASH_USER_START_ADDR;
  a = 0;
  while (Address < FLASH_USER_END_ADDR)
  {
    buf[a++] = *(__IO uint32_t *)Address;
    Address = Address + 4;
  }

  memset(&buf[Setting_Number * 60], 0, 60);         // Clear setting value
  memcpy(&buf[Setting_Number * 60], &value[0], length); // Set setting value

  Erase_User_Flash_Memory();

  HAL_FLASH_Unlock();

  Address = FLASH_USER_START_ADDR;
  a = 0;

  while (Address < FLASH_USER_END_ADDR)
  {
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, buf[a++]) == HAL_OK)
    {
        Address = Address + 4;
    }
   else
    {
      /* Error occurred while writing data in Flash memory.
         User can add here some code to deal with this error */
      while (1)
      {
        /* Make LED1 blink (100ms on, 2s off) to indicate error in Write operation */
        BSP_LED_On(LED1);
        HAL_Delay(100);
        BSP_LED_Off(LED1);
        HAL_Delay(2000);
      }
    }
  }

  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  HAL_FLASH_Lock();
}

Я изменил это на самом деле, после считывания настроек из флэш-памяти в буфер, обновите все измененные настройки в буфере, затем сотрите блок флэш-памяти и запишите буфер обратно во флэш-память. Недостаток: мои первое и четвертое значения всегда возвращаются как NULL после сохранения этого буфера во флэш-памяти.

Однако после сброса системы правильные значения считываются с флэш-памяти.

unsigned char Save_Settings(Save_Settings_struct* newSettings)
{
  /* Program the user Flash area word by word
    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
  unsigned int a;
  unsigned char readBack[60];

  Address = FLASH_USER_START_ADDR;
  a = 0;
  while (Address < FLASH_USER_END_ADDR)
  {
    buf[a++] = *(__IO uint32_t *)Address;
    Address = Address + 4;
  }

  a = 0;

  while (a < S_MAXSETTING)
  {
      if (newSettings[a].settingNumber < S_MAXSETTING)
      {
          memset(&buf[a * 60], 0, 60);          // Clear setting value
          memcpy(&buf[a * 60], newSettings[a].settingValue, newSettings[a].settingLength);  // Set setting value
      }

      ++a;
  }

  Erase_User_Flash_Memory();

  HAL_FLASH_Unlock();

  Address = FLASH_USER_START_ADDR;
  a = 0;

  while (Address < FLASH_USER_END_ADDR)
  {
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, buf[a++]) == HAL_OK)
    {
        Address = Address + 4;
    }
   else
    {
      /* Error occurred while writing data in Flash memory.
         User can add here some code to deal with this error */
      while (1)
      {
        /* Make LED1 blink (100ms on, 2s off) to indicate error in Write operation */
        BSP_LED_On(LED1);
        HAL_Delay(100);
        BSP_LED_Off(LED1);
        HAL_Delay(2000);
      }
    }
  }

  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  HAL_FLASH_Lock();
}

Я начал играть с очисткой и аннулированием кэша данных. По крайней мере, эти 2 значения больше не равны NULL, однако они все еще являются старыми значениями. Все остальные значения являются новыми, сохраненными значениями. Сделайте сброс, и все значения верны.

У кого-нибудь когда-нибудь были подобные проблемы? Или может быть идея о том, что я могу попытаться избавиться от этой проблемы?

...