Перейти к содержанию
    

Инициализация структуры во Flash

Добрый день , подскажите как можно продублировать инициализированную структуры во flash.

Дело в том, что понадобилось сохранять настройки программы в flash, но для зашиты их решил сделать несколько дубликатов.

Делаю это примерно так:

S_GlobalSettingAllVar DefaultGlobalSettingAllVar={ //Начальные настройки(устанавливаются после нажатия кнопки Reset)
   .NetSetting={
      .mac = {0x00, 0x08, 0xdc, 0xab, 0xc1, 0x11},   //6
      .ip = {192, 168, 1, 4},                     //4
      .sn = {255, 255, 0, 0},
      .gw = {192, 168, 0, 0},
   },
   .Password={"fghfgh"},
}
S_GlobalSettingAllVar GlobalSettingAllVar={ //рабочая структура
   .NetSetting={
      .mac = {0x00, 0x08, 0xdc, 0xab, 0xc1, 0x11},   //6
      .ip = {192, 168, 1, 4},                     //4
      .sn = {255, 255, 0, 0},
      .gw = {192, 168, 0, 0},
   },
   .Password={"fghfgh"},
}

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

Хотелось бы сделать инициализацию в одной из структур, которая при прошивки разместилась по нескольким адресам.

 

Как заставить компилятор разместить структуры во flash даже если по коду они не используются?(по коду использую адрес)

 

Ps. компилятор IAR stm32, но думаю это не сильно принципиально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скопировать пословно. У меня есть структуры с текущим режимом работы и с новым, полученным с панели управления. Когда отрабатываю заданный режим, копирую новую структуру в текущую. Только у меня энергонезависимая ОЗУ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дело в том, что понадобилось сохранять настройки программы в flash, но для зашиты их решил сделать несколько дубликатов.

А какой сакральный смысл в нескольких копиях во флешь?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какой сакральный смысл в нескольких копиях во флешь?

Дело в том что что бы перезаписать байт надо обновить всю структуру для этого всю страницу надо стереть и если в этот момент произойдут сбой питания, то все настройки слетят.

 

У меня алгоритм такой.

1) после включении программы происходит копирование одной из структур в ОЗУ.

2) сравнение по байтно 3 массива и если 2 байт из разных копиях верны а третий байт нет то он заменяется из двух совпавшим(структура в ОЗУ).

3) Если был сбой(какой-то из 3х копий не совпал), то перезаписываем все 3 копии восстановленными данными(В ОЗУ)

 

Таким образом в случае потери одной из копий настроек (после броска питания) она будет восстановлена после перезагрузки.

 

Сергей Борщ, в моем случае надо сначала установить минимальные настройки, а потом их уже корректировать, по этому не было такой нужны в CRC, хотя я уже обдумывал о неком флаге в flash который бы указывал что надо продублировать настройки после чего сбрасывался и не когда больше не выставлялся.

Но я считаю такой подходи не совсем правильным так как, всё это можно сделать при прошивки процессора. По этому надеялся на то что можно выделить секцию под настройки и указать линкекру разместить её в нескольких местах (может написал фигню с секциями и линкером не работал).

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А ещё лучше поставить сбоку FRAM и вообще больше не париться.

Писать что угодно, куда, когда и сколько угодно раз.

Счетчик моточасов, например, ежесекундно переписывать.

 

А с флешью я нынче работаю так:

есть несколько сегментов, в которых лежат одинаковые копии данных, подписанные CRC.

 

При считывании проверяется CRC и при несовпадении считывается следующая копия, а испорченная восстанавливается.

При записи происходит проверка целостности.

 

Если все копии испорчены (не представляю, как такое может случиться) записываются дефолтные данные. Собственно, это происходит при первом включении, когда в инфо сегментах FF..FF

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А с флешью я нынче работаю так:

есть несколько сегментов, в которых лежат одинаковые копии данных, подписанные CRC.

Как такое указать компилятору?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По этому надеялся на то что можно выделить секцию под настройки и указать линкекру разместить её в нескольких местах (может написал фигню с секциями и линкером не работал).

#pragma location (емнип), reed IAR Compiler Reference

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, у меня тоже есть CRC в структурах. Если она не верна (проверяется при включении), записываю структуру дефолтными данными. CRC вычисляется и записывается при переносе режимов из новой структуры в старую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) после включении программы происходит копирование одной из структур в ОЗУ.

2) сравнение по байтно 3 массива и если 2 байт из разных копиях верны а третий байт нет то он заменяется из двух совпавшим(структура в ОЗУ).

3) Если был сбой(какой-то из 3х копий не совпал), то перезаписываем все 3 копии восстановленными данными(В ОЗУ)

Таким образом в случае потери одной из копий настроек (после броска питания) она будет восстановлена после перезагрузки.

Если был какой-то сбой, то скорей всего у Вас часть структуры окажется стёртой (заполненной FF например) и запросто совпадёт с другой тоже стёртой и вместе они уничтожат 3-ю валидную структуру :)

Лучше, как тут уже советовали, дополнить структуру CRC, хранить достаточно 2 копии, и в каждой копии хранить дополнительно счётчик износа FLASH.

Перед обновлением структуры, выбираете в какой из копий счётчик меньше, создаёте в ОЗУ новый образ для записи (с инкрементированным счётчиком) дополненный CRC.

Стираете и записываете поверх структуры с минимальным счётчиком.

Если же при старте ПО окажется, что одна из копий или пуста или содержит неверную CRC, то для след. записи выбирается именно она, вне зависимости от счётчика, а начальное значение счётчика берётся из другой структуры (валидной) увеличенное на 1.

И хранить в ОЗУ копию не надо (зачем тратить ОЗУ?), раз структура находится во FLASH МК. Достаточно хранить указатель на валидную копию структуры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я делал так

void LoadFlashParams(void)
{
    //load the data from the first page
    memcpy(&flashParams, (uint32_t*)FLASH_PAGE125, sizeof(flashParams));
    uint32_t crc = crc32(0, (uint8_t*)&flashParams, sizeof(flashParams));
    if (crc != flashParams.crc)  //the first page damaged or the first time load
    {
        //load the data from a second page
        memcpy(&flashParams, (uint32_t*)FLASH_PAGE126, sizeof(flashParams));
        crc = crc32(0, (uint8_t*)&flashParams, sizeof(flashParams));
        if (crc != flashParams.crc)  //the second page damaged or the first time load
        {
            //two pages failed - initialize parameters, don't write to flash
            //INITIALIZATION OF STRUCT

            crc = crc32(0, (uint8_t*)&flashParams, sizeof(flashParams));
            flashParams.crc = crc;

            //WriteToFlash(FLASH_PAGE125);
            //WriteToFlash(FLASH_PAGE126);
        }
        else  //second page OK
        {
            //backup the data on the first page
            WriteToFlash(FLASH_PAGE125);
        }
    }
    else  //first page OK
    {
        //load the data from a second page
        memcpy(&flashParams, (uint32_t*)FLASH_PAGE126, sizeof(flashParams));
        crc = crc32(0, (uint8_t*)&flashParams, sizeof(flashParams));
        if (crc != flashParams.crc)  //the second page damaged
        {
            //backup the data on the second page
            WriteToFlash(FLASH_PAGE126);
        }
    }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если был какой-то сбой, то скорей всего у Вас часть структуры окажется стёртой (заполненной FF например) и запросто совпадёт с другой тоже стёртой и вместе они уничтожат 3-ю валидную структуру sm.gif

С чего копии окажутся стертыми? Каждая копия находится на разных страницах, тем самым когда произвожу стирание то уничтожается только 1 копия.

 

И хранить в ОЗУ копию не надо (зачем тратить ОЗУ?), раз структура находится во FLASH МК. Достаточно хранить указатель на валидную копию структуры.

А как тогда перезаписать структуру ? в любом случае её надо будет считать в озу обновить и записать. В моем варианте первый шаг отбрасывается.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С чего копии окажутся стертыми? Каждая копия находится на разных страницах, тем самым когда произвожу стирание то уничтожается только 1 копия.

Потому что подали команду стирания и в этот момент сбой питания произошёл.

И какой же у Вас процесс модификации структуры? Вот изменилась она, что делаете? Все 3 переписываете? Или как?

 

А как тогда перезаписать структуру ? в любом случае её надо будет считать в озу обновить и записать. В моем варианте первый шаг отбрасывается.

В Вашем варианте я не понимаю как Вы переписываете эти структуры чтобы было безопасно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

. . . .

 

Сергей Борщ, в моем случае надо . . . . ., по этому не было такой нужны в CRC . . . .

 

Есть люди, которые свято верят, что CRC следует использовать только когда надо .

Наприимер, если соединительный провод между приборами 1-2-3 м, то использование CRC излишне и вредит :)

(намек на "надежный канал связи").

Если бы с таким подходом был заложен стандарт на Ethernet/IP - сидели бы мы до сих пор без www.

Изменено пользователем k155la3

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И какой же у Вас процесс модификации структуры? Вот изменилась она, что делаете? Все 3 переписываете? Или как?

Да все три по очереди, стереть первую копию записать, стереть вторую копию записать...

void Write_SettingVAR_flash(void){
    //-------------------------------------------------
    FLASH->KEYR = FLASH_KEY1;
    FLASH->KEYR = FLASH_KEY2;
    //-----------------------------------------------------------------------------------------------------
    FLASH_ErasePage(ADDR_FLASH_CONST);
    FLASH_ProgramPage(ADDR_FLASH_CONST,(unsigned char*)&Global_Flash_SettingAllVar,Table_flash_Setting_len);
    //-----------------------------------------------------------------------------------------------------
    FLASH_ErasePage(ADDR_DUBLE1_FLASH_CONST);
    FLASH_ProgramPage(ADDR_DUBLE1_FLASH_CONST,(unsigned char*)&Global_Flash_SettingAllVar,Table_flash_Setting_len);
    //-----------------------------------------------------------------------------------------------------
    FLASH_ErasePage(ADDR_DUBLE2_FLASH_CONST);
    FLASH_ProgramPage(ADDR_DUBLE2_FLASH_CONST,(unsigned char*)&Global_Flash_SettingAllVar,Table_flash_Setting_len);
    //-----------------------------------------------------------------------------------------------------
    FLASH->CR |= FLASH_CR_LOCK; /* Lock the flash back */
    //-----------------------------------------------------------------------------------------------------
}

Потому что подали команду стирания и в этот момент сбой питания произошёл.

Это может произойти только в одном из копий и она да повредится, остальные копии уже записались либо ещё не стерлись.

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...