Stm32f746 чтение флэш-памяти после записи возвращает ноль

Сохраняю настройки во флеш-память и снова читаю их. 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();
}

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

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

У вас есть 13 настроек с фиксированной длиной 60 байт каждая, что составляет 780 байт, верно? Как это соотносится с размером вашего блока, который может составлять 512 байт?

Mark Setchell 29.08.2018 21:38

Извините, но я не думаю, что это проблема. Секторы правильно обрабатываются нижним уровнем в зависимости от адреса, по которому вы хотите сохранить. На этом (текущем) уровне не должно быть никакой низкоуровневой обработки, и обработка секторов здесь в основном прозрачна.

user5763204 31.08.2018 22:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
368
0

Другие вопросы по теме