реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Инициализация структуры во Flash, Дублирование области flash
pokk
сообщение May 24 2016, 04:27
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Добрый день , подскажите как можно продублировать инициализированную структуры во 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, но думаю это не сильно принципиально.
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 24 2016, 04:42
Сообщение #2


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Скопировать пословно. У меня есть структуры с текущим режимом работы и с новым, полученным с панели управления. Когда отрабатываю заданный режим, копирую новую структуру в текущую. Только у меня энергонезависимая ОЗУ.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 24 2016, 04:51
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(pokk @ May 24 2016, 10:27) *
Дело в том, что понадобилось сохранять настройки программы в flash, но для зашиты их решил сделать несколько дубликатов.

А какой сакральный смысл в нескольких копиях во флешь?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 24 2016, 05:34
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (pokk @ May 24 2016, 07:27) *
В принципе можно так же сделать и дублирующие структуры
В ваших структурах есть один большой недостаток - в них нет никакой контрольной суммы, а значит у вас нет критерия для выбора - какая из этих копий содержит правильные данные. Я в своих программах делаю так: в программе хранится один образ настроек "по-умолчанию", в отдельном сегменте для настроек хранятся текущие настройки. В самих исходниках этим текущим настройкам никакое значение не присвоено, этот сегмент даже помечен как незагружаемый, чтобы не забивать настройки заново после каждой перепрошивки. При запуске программа считает контрольную сумму текущих настроек и, если она не совпала, переписывает текущие настройки значениями "по-умолчанию". Вы можете считать контрольную сумму всех копий и копировать в остальные ту, у которой контрольная сумма совпала, но не забудьте каждую копию разместить в своей странице флеша.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
pokk
сообщение May 24 2016, 06:35
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



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

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

У меня алгоритм такой.
1) после включении программы происходит копирование одной из структур в ОЗУ.
2) сравнение по байтно 3 массива и если 2 байт из разных копиях верны а третий байт нет то он заменяется из двух совпавшим(структура в ОЗУ).
3) Если был сбой(какой-то из 3х копий не совпал), то перезаписываем все 3 копии восстановленными данными(В ОЗУ)

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

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




Go to the top of the page
 
+Quote Post
MrYuran
сообщение May 24 2016, 06:42
Сообщение #6


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



А ещё лучше поставить сбоку FRAM и вообще больше не париться.
Писать что угодно, куда, когда и сколько угодно раз.
Счетчик моточасов, например, ежесекундно переписывать.

А с флешью я нынче работаю так:
есть несколько сегментов, в которых лежат одинаковые копии данных, подписанные CRC.

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

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


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
pokk
сообщение May 24 2016, 06:45
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Цитата
А с флешью я нынче работаю так:
есть несколько сегментов, в которых лежат одинаковые копии данных, подписанные CRC.

Как такое указать компилятору?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение May 24 2016, 06:45
Сообщение #8


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(pokk @ May 24 2016, 09:35) *
По этому надеялся на то что можно выделить секцию под настройки и указать линкекру разместить её в нескольких местах (может написал фигню с секциями и линкером не работал).

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


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 24 2016, 06:48
Сообщение #9


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Да, у меня тоже есть CRC в структурах. Если она не верна (проверяется при включении), записываю структуру дефолтными данными. CRC вычисляется и записывается при переносе режимов из новой структуры в старую.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 24 2016, 08:40
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(pokk @ May 24 2016, 12:35) *
1) после включении программы происходит копирование одной из структур в ОЗУ.
2) сравнение по байтно 3 массива и если 2 байт из разных копиях верны а третий байт нет то он заменяется из двух совпавшим(структура в ОЗУ).
3) Если был сбой(какой-то из 3х копий не совпал), то перезаписываем все 3 копии восстановленными данными(В ОЗУ)
Таким образом в случае потери одной из копий настроек (после броска питания) она будет восстановлена после перезагрузки.

Если был какой-то сбой, то скорей всего у Вас часть структуры окажется стёртой (заполненной FF например) и запросто совпадёт с другой тоже стёртой и вместе они уничтожат 3-ю валидную структуру sm.gif
Лучше, как тут уже советовали, дополнить структуру CRC, хранить достаточно 2 копии, и в каждой копии хранить дополнительно счётчик износа FLASH.
Перед обновлением структуры, выбираете в какой из копий счётчик меньше, создаёте в ОЗУ новый образ для записи (с инкрементированным счётчиком) дополненный CRC.
Стираете и записываете поверх структуры с минимальным счётчиком.
Если же при старте ПО окажется, что одна из копий или пуста или содержит неверную CRC, то для след. записи выбирается именно она, вне зависимости от счётчика, а начальное значение счётчика берётся из другой структуры (валидной) увеличенное на 1.
И хранить в ОЗУ копию не надо (зачем тратить ОЗУ?), раз структура находится во FLASH МК. Достаточно хранить указатель на валидную копию структуры.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение May 24 2016, 10:27
Сообщение #11


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



я делал так
Код
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);
        }
    }
}
Go to the top of the page
 
+Quote Post
pokk
сообщение May 24 2016, 10:30
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



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

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

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

А как тогда перезаписать структуру ? в любом случае её надо будет считать в озу обновить и записать. В моем варианте первый шаг отбрасывается.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 25 2016, 04:59
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(pokk @ May 24 2016, 16:30) *
С чего копии окажутся стертыми? Каждая копия находится на разных страницах, тем самым когда произвожу стирание то уничтожается только 1 копия.

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

Цитата(pokk @ May 24 2016, 16:30) *
А как тогда перезаписать структуру ? в любом случае её надо будет считать в озу обновить и записать. В моем варианте первый шаг отбрасывается.

В Вашем варианте я не понимаю как Вы переписываете эти структуры чтобы было безопасно?
Go to the top of the page
 
+Quote Post
k155la3
сообщение May 25 2016, 06:01
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(pokk @ May 24 2016, 09:35) *
. . . .

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


Есть люди, которые свято верят, что CRC следует использовать только когда надо .
Наприимер, если соединительный провод между приборами 1-2-3 м, то использование CRC излишне и вредит sm.gif
(намек на "надежный канал связи").
Если бы с таким подходом был заложен стандарт на Ethernet/IP - сидели бы мы до сих пор без www.

Сообщение отредактировал k155la3 - May 25 2016, 06:03
Go to the top of the page
 
+Quote Post
pokk
сообщение May 25 2016, 09:13
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Цитата
И какой же у Вас процесс модификации структуры? Вот изменилась она, что делаете? Все 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 */
    //-----------------------------------------------------------------------------------------------------
}

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

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



Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 23:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01493 секунд с 7
ELECTRONIX ©2004-2016