Я сохраняю настройки на флэш-память и читаю их снова. 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, однако они все еще являются старыми значениями. Все остальные значения являются новыми, сохраненными значениями. Сделайте сброс, и все значения верны.
У кого-нибудь когда-нибудь была подобная проблема? Или может быть идея о том, что я могу попытаться избавиться от этой проблемы?
Задача ещё не решена.
Других решений пока нет …