pokk 0 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба Добрый день , подскажите как можно продублировать инициализированную структуры во 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, но думаю это не сильно принципиально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба Скопировать пословно. У меня есть структуры с текущим режимом работы и с новым, полученным с панели управления. Когда отрабатываю заданный режим, копирую новую структуру в текущую. Только у меня энергонезависимая ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба Дело в том, что понадобилось сохранять настройки программы в flash, но для зашиты их решил сделать несколько дубликатов. А какой сакральный смысл в нескольких копиях во флешь? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба В принципе можно так же сделать и дублирующие структурыВ ваших структурах есть один большой недостаток - в них нет никакой контрольной суммы, а значит у вас нет критерия для выбора - какая из этих копий содержит правильные данные. Я в своих программах делаю так: в программе хранится один образ настроек "по-умолчанию", в отдельном сегменте для настроек хранятся текущие настройки. В самих исходниках этим текущим настройкам никакое значение не присвоено, этот сегмент даже помечен как незагружаемый, чтобы не забивать настройки заново после каждой перепрошивки. При запуске программа считает контрольную сумму текущих настроек и, если она не совпала, переписывает текущие настройки значениями "по-умолчанию". Вы можете считать контрольную сумму всех копий и копировать в остальные ту, у которой контрольная сумма совпала, но не забудьте каждую копию разместить в своей странице флеша. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба А какой сакральный смысл в нескольких копиях во флешь? Дело в том что что бы перезаписать байт надо обновить всю структуру для этого всю страницу надо стереть и если в этот момент произойдут сбой питания, то все настройки слетят. У меня алгоритм такой. 1) после включении программы происходит копирование одной из структур в ОЗУ. 2) сравнение по байтно 3 массива и если 2 байт из разных копиях верны а третий байт нет то он заменяется из двух совпавшим(структура в ОЗУ). 3) Если был сбой(какой-то из 3х копий не совпал), то перезаписываем все 3 копии восстановленными данными(В ОЗУ) Таким образом в случае потери одной из копий настроек (после броска питания) она будет восстановлена после перезагрузки. Сергей Борщ, в моем случае надо сначала установить минимальные настройки, а потом их уже корректировать, по этому не было такой нужны в CRC, хотя я уже обдумывал о неком флаге в flash который бы указывал что надо продублировать настройки после чего сбрасывался и не когда больше не выставлялся. Но я считаю такой подходи не совсем правильным так как, всё это можно сделать при прошивки процессора. По этому надеялся на то что можно выделить секцию под настройки и указать линкекру разместить её в нескольких местах (может написал фигню с секциями и линкером не работал). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба А ещё лучше поставить сбоку FRAM и вообще больше не париться. Писать что угодно, куда, когда и сколько угодно раз. Счетчик моточасов, например, ежесекундно переписывать. А с флешью я нынче работаю так: есть несколько сегментов, в которых лежат одинаковые копии данных, подписанные CRC. При считывании проверяется CRC и при несовпадении считывается следующая копия, а испорченная восстанавливается. При записи происходит проверка целостности. Если все копии испорчены (не представляю, как такое может случиться) записываются дефолтные данные. Собственно, это происходит при первом включении, когда в инфо сегментах FF..FF Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба А с флешью я нынче работаю так: есть несколько сегментов, в которых лежат одинаковые копии данных, подписанные CRC. Как такое указать компилятору? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба По этому надеялся на то что можно выделить секцию под настройки и указать линкекру разместить её в нескольких местах (может написал фигню с секциями и линкером не работал). #pragma location (емнип), reed IAR Compiler Reference Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба Да, у меня тоже есть CRC в структурах. Если она не верна (проверяется при включении), записываю структуру дефолтными данными. CRC вычисляется и записывается при переносе режимов из новой структуры в старую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба 1) после включении программы происходит копирование одной из структур в ОЗУ. 2) сравнение по байтно 3 массива и если 2 байт из разных копиях верны а третий байт нет то он заменяется из двух совпавшим(структура в ОЗУ). 3) Если был сбой(какой-то из 3х копий не совпал), то перезаписываем все 3 копии восстановленными данными(В ОЗУ) Таким образом в случае потери одной из копий настроек (после броска питания) она будет восстановлена после перезагрузки. Если был какой-то сбой, то скорей всего у Вас часть структуры окажется стёртой (заполненной FF например) и запросто совпадёт с другой тоже стёртой и вместе они уничтожат 3-ю валидную структуру :) Лучше, как тут уже советовали, дополнить структуру CRC, хранить достаточно 2 копии, и в каждой копии хранить дополнительно счётчик износа FLASH. Перед обновлением структуры, выбираете в какой из копий счётчик меньше, создаёте в ОЗУ новый образ для записи (с инкрементированным счётчиком) дополненный CRC. Стираете и записываете поверх структуры с минимальным счётчиком. Если же при старте ПО окажется, что одна из копий или пуста или содержит неверную CRC, то для след. записи выбирается именно она, вне зависимости от счётчика, а начальное значение счётчика берётся из другой структуры (валидной) увеличенное на 1. И хранить в ОЗУ копию не надо (зачем тратить ОЗУ?), раз структура находится во FLASH МК. Достаточно хранить указатель на валидную копию структуры. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба я делал так 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); } } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 24 мая, 2016 Опубликовано 24 мая, 2016 · Жалоба Если был какой-то сбой, то скорей всего у Вас часть структуры окажется стёртой (заполненной FF например) и запросто совпадёт с другой тоже стёртой и вместе они уничтожат 3-ю валидную структуру sm.gif С чего копии окажутся стертыми? Каждая копия находится на разных страницах, тем самым когда произвожу стирание то уничтожается только 1 копия. И хранить в ОЗУ копию не надо (зачем тратить ОЗУ?), раз структура находится во FLASH МК. Достаточно хранить указатель на валидную копию структуры. А как тогда перезаписать структуру ? в любом случае её надо будет считать в озу обновить и записать. В моем варианте первый шаг отбрасывается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 25 мая, 2016 Опубликовано 25 мая, 2016 · Жалоба С чего копии окажутся стертыми? Каждая копия находится на разных страницах, тем самым когда произвожу стирание то уничтожается только 1 копия. Потому что подали команду стирания и в этот момент сбой питания произошёл. И какой же у Вас процесс модификации структуры? Вот изменилась она, что делаете? Все 3 переписываете? Или как? А как тогда перезаписать структуру ? в любом случае её надо будет считать в озу обновить и записать. В моем варианте первый шаг отбрасывается. В Вашем варианте я не понимаю как Вы переписываете эти структуры чтобы было безопасно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 25 мая, 2016 Опубликовано 25 мая, 2016 (изменено) · Жалоба . . . . Сергей Борщ, в моем случае надо . . . . ., по этому не было такой нужны в CRC . . . . Есть люди, которые свято верят, что CRC следует использовать только когда надо . Наприимер, если соединительный провод между приборами 1-2-3 м, то использование CRC излишне и вредит :) (намек на "надежный канал связи"). Если бы с таким подходом был заложен стандарт на Ethernet/IP - сидели бы мы до сих пор без www. Изменено 25 мая, 2016 пользователем k155la3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 25 мая, 2016 Опубликовано 25 мая, 2016 · Жалоба И какой же у Вас процесс модификации структуры? Вот изменилась она, что делаете? Все 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 */ //----------------------------------------------------------------------------------------------------- } Потому что подали команду стирания и в этот момент сбой питания произошёл. Это может произойти только в одном из копий и она да повредится, остальные копии уже записались либо ещё не стерлись. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться