Alex_7211 0 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба Отгородил себе флэш для энергонезависимых настроек: uint16_t ID[256] __attribute__((at(0x00007E00))) = {0, 1, 0x05E0}; Какое-то время всё было хорошо: читалось по имени и стиралось/перезаписывалось по абсолютному адресу. Но в какой-то момент при прошивке там стало появляться такое: ID[0] = 0x1221 вместо 0 ID[1] = 0x0A01 вместо 1 ID[3] = 0xE0FF вместо 0x05E0 Перезапись из программы по абсолютным адресам работает и дальше всё ОК. Только начальные значения какие-то левые. Вот как эта секция выглядит в map-файле: Load Region LR$$.ARM.__AT_0x00007E00 (Base: 0x00007e00, Size: 0x00000200, Max: 0x00000200, ABSOLUTE, COMPRESSED[0x0000000c]) Execution Region ER$$.ARM.__AT_0x00007E00 (Exec base: 0x00007e00, Load base: 0x00007e00, Size: 0x00000200, Max: 0x00000200, ABSOLUTE, UNINIT, COMPRESSED[0x0000000c]) Exec Addr Load Addr Size Type Attr Idx E Section Name Object 0x00007e00 COMPRESSED 0x00000200 Data RW 28 .ARM.__AT_0x00007E00 bvd302main.o И вот как она выглядела, когда всё работало: Load Region LR$$.ARM.__AT_0x00007E00 (Base: 0x00007e00, Size: 0x00000200, Max: 0x00000200, ABSOLUTE) Execution Region ER$$.ARM.__AT_0x00007E00 (Exec base: 0x00007e00, Load base: 0x00007e00, Size: 0x00000200, Max: 0x00000200, ABSOLUTE, UNINIT) Exec Addr Load Addr Size Type Attr Idx E Section Name Object 0x00007e00 0x00007e00 0x00000200 Data RW 26 .ARM.__AT_0x00007E00 bvd302main.o Что нахрен за COMPRESSED появилось? Я ничо особого не делал, просто добавил немного кода, не относящегося к этой секции. Свободной флэш-памяти - процентов 80. В компиляторе пробовал менять уровни оптимизации - не помогает. Объявление volatile не помогает. Подскажите, как вернуть обратно абсолютный Load Addr и убрать этот COMPRESSED? Кажется, что дело в нем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 5 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба Вы уверены, что отключение сжатия поможет? Тогда: в опциях линкера указать --datacompressor off Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 1 час назад, Alex_7211 сказал: Отгородил себе флэш для энергонезависимых настроек: uint16_t ID[256] __attribute__((at(0x00007E00))) = {0, 1, 0x05E0}; А const где? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_7211 0 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 3 часа назад, VladislavS сказал: А const где? Если я ставлю const, то сектор меняет атрибут RW на RO и перестает стираться/записываться из программы (!) почему-то. Я пробовал. Если это имеет значение, то проц NXP MKE06Z64VLH4 на ядре M0+. Частичная или полная блокировка записи во флэш задается в startXXX.s и там весь флэш открыт для записи. Дальше копать не стал. Работает как переменная и ладно. 3 часа назад, Палыч сказал: Вы уверены, что отключение сжатия поможет? Тогда: в опциях линкера указать --datacompressor off Перекомпилировал. "Compressed" исчезло. Кажется это оно. Завтра перешью, проверю. Спасибо вам, добрый человек! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 1 час назад, Alex_7211 сказал: Работает как переменная и ладно. Flash как переменная? Барин знает толк в извращениях... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 17 июня, 2020 Опубликовано 17 июня, 2020 · Жалоба 3 часа назад, Alex_7211 сказал: Если я ставлю const, то сектор меняет атрибут RW на RO и перестает стираться/записываться из программы (!) почему-то. Я пробовал. Это вообще не понятно. Такого не должно быть. Компрессия данных применяется линкером ТОЛЬКО для секций с атрибутом RW. Для RO не применяется. Причем она по-умолчанию включена. Линкер думает, что это ОЗУ и вставляет до main() код декомпрессии и записи туда начальных значений. Т.к. это не ОЗУ, а флеш, то к требуемому результату это не приводит. Но остается вопрос: а почему там не 0хFFFF во всех элементах массива? Значит, перед программированием эта область памяти не стирается, и там остается мусор? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_7211 0 18 июня, 2020 Опубликовано 18 июня, 2020 · Жалоба 13 часов назад, Alex_7211 сказал: Перекомпилировал. "Compressed" исчезло. Кажется это оно. Завтра перешью, проверю. Спасибо вам, добрый человек! Спасибо Палычу, изгоняющему бесов! Всё работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_7211 0 18 июня, 2020 Опубликовано 18 июня, 2020 · Жалоба 9 часов назад, Darth Vader сказал: Компрессия данных применяется линкером ТОЛЬКО для секций с атрибутом RW. Для RO не применяется. Так я же и пишу, что объявляю массив как переменную, которая получает атрибут RW, несмотря на область Flash. При этом всё работало, за исключением компрессии, которая появилась не сразу и стала портить начальные значения. Почему не 0xFFFF - потому что я инициализирую первые 6 байт при объявлении массива. В настройках программатора стоит "erase full chip". Когда я, как человек воспитанный, объявлял массив const и он получал RO, то не работало стирание из программы - всегда ошибка. Это были мои вторые грабли при работе с Flash. Первые - в модуле MCM установить Enable Stalling Flash Controller, иначе reset сразу при попытке стирания. Возможно, в этом модуле нужно было что-то еще подшаманить, чтобы const заработал, ХЗ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 180 18 июня, 2020 Опубликовано 18 июня, 2020 · Жалоба 1 час назад, Alex_7211 сказал: Почему не 0xFFFF - потому что я инициализирую первые 6 байт при объявлении массива. В настройках программатора стоит "erase full chip". Интересно, а что-же с остальными байтами массива по Вашему мнению? Я вот к сожалению не знаю способа в си инициализировать только часть массива. 1 час назад, Alex_7211 сказал: Когда я, как человек воспитанный, объявлял массив const и он получал RO, то не работало стирание из программы - всегда ошибка. Это были мои вторые грабли при работе с Flash. Я конечно не особо знаком с Keil, но всё-таки не очень понимаю - чего вы пытаетесь добиться этим?: 20 часов назад, Alex_7211 сказал: Load Region LR$$.ARM.__AT_0x00007E00 (Base: 0x00007e00, Size: 0x00000200, Max: 0x00000200, ABSOLUTE, COMPRESSED[0x0000000c]) Execution Region ER$$.ARM.__AT_0x00007E00 (Exec base: 0x00007e00, Load base: 0x00007e00, Size: 0x00000200, Max: 0x00000200, ABSOLUTE, UNINIT, COMPRESSED[0x0000000c]) Exec Addr Load Addr Size Type Attr Idx E Section Name Object 0x00007e00 COMPRESSED 0x00000200 Data RW 28 .ARM.__AT_0x00007E00 bvd302main.o Чтобы при каждом включении устройства, оно каждый раз стирало и записывало флешь? (ведь как я понимаю - по адресу 0x7E00 находится флешь в вашем МК?). Это такой тест на количество циклов перезаписи флеша? Ну так и тест кривой - надо паттерн-то менять, а то ведь умный загрузчик возьмёт развернёт эту COMPRESSED-секцию инициализации в отдельную память, сравнит с целевой областью памяти и не станет стирать (так как они равны). И чем не нравится COMPRESSED? Имхо (если я правильно догадываюсь о его назначении), оно позволяет уменьшить объём секции инициализации переменных, хранящейся во флешь. Ведь у Вас там этот массив инициализируется в основном нулями, и COMPRESSED видимо позволяет линкеру вместо 253 слов нулей записать только пару значение/счётчик_повтора. А убиранием "COMPRESSED" Вы добились только увеличиения секции инициализации данных до полных 256 слов. Тоже не понимаю - зачем??? PS: Советую прислушаться к 14 часов назад, VladislavS сказал: Flash как переменная? Барин знает толк в извращениях.. и подумать о том, что поисходит при старте вашей программы в устройстве. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_7211 0 18 июня, 2020 Опубликовано 18 июня, 2020 · Жалоба 55 минут назад, jcxz сказал: чего вы пытаетесь добиться этим?: Энергонезависимые настройки, которые можно поменять из программы. И новые настройки снова будут энергонезависимыми. Все же так делают, нет? 56 минут назад, jcxz сказал: Интересно, а что-же с остальными байтами массива по Вашему мнению? Keil забивает их нулями. Проверено. Но у меня есть более гуманный к Flash вариант и я забиваю все остальные 253 0xFFFF при объявлении. 58 минут назад, jcxz сказал: Чтобы при каждом включении устройства, оно каждый раз стирало и записывало флешь? Нет. Кто "оно"? Всё работает ОК. Все данные сохраняются, не переинициализируются первоначальными данными из прошивки, а сохраняются последние записанные. Вы наверное слабо представляете себе перезапись флэш из программы. Тут хрен можно сломать. Компиллятор уж точно ничего не подставит от себя. Слишком чипо-зависимо. 1 час назад, jcxz сказал: умный загрузчик не пользуюсь 1 час назад, jcxz сказал: И чем не нравится COMPRESSED? Нельзя уменьшать размер секции. 512 байт - минимальная секция для стирания. 1 час назад, jcxz сказал: и подумать о том, что поисходит при старте Прекрасно отдаю себе отчет. Вообще вот просто по шагам и по тактам. 1 час назад, jcxz сказал: Тоже не понимаю - зачем??? Не понимаете - спросите. Не сочтите за грубость, но чё-то закрадываются сомнения, что вы писали во флэш. В NXP, STM, в PIC везде есть минимальная страница стирания и очень (специально!) мудреный доступ к командам стирания/записи. В общем, вопрос исчерпан, спасибо всем за внимание. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 180 18 июня, 2020 Опубликовано 18 июня, 2020 · Жалоба 30 минут назад, Alex_7211 сказал: Энергонезависимые настройки, которые можно поменять из программы. И новые настройки снова будут энергонезависимыми. Все же так делают, нет? Пытаются записывать настройки во флешь из стартап-кода? Думаю так делаете только Вы. А большинство делают это из своей программы, собственной функцией записи флешь. Цитата Нет. Кто "оно"? Всё работает ОК. Все данные сохраняются, не переинициализируются первоначальными данными из прошивки, а сохраняются последние записанные. Оно - это сишный стартап код, которому Вы пытаетесь указать записать данные во флешь, разместив RW-секцию данных с начальной инициализацией во флешь. Чтобы проинициализировать такую секцию, стартап коду как раз надо уметь стирать/писать флешь. Может он это и умеет, может и нет - не знаю, но сильно сомневаюсь. А раз "данные не переинициализируются первоначальными данными из прошивки", то это и говорит как раз о том, что стартап код не умеет писать во флешь. А просто игнорит ваши инициализационные данные. Просто повезло, что в hard fault при этом не падает. Цитата Вы наверное слабо представляете себе перезапись флэш из программы. Тут хрен можно сломать. Компиллятор уж точно ничего не подставит от себя. Слишком чипо-зависимо. Я думаю это Вы слабо представляете мои знания о записи флешь. Цитата не пользуюсь Под таким "загрузчиком" я имел в виду стандартный сишный стартап. Цитата Прекрасно отдаю себе отчет. Вообще вот просто по шагам и по тактам. Тогда что по вашему должно происходить при старте программы? при наличии в коде такого: 22 часа назад, Alex_7211 сказал: uint16_t ID[256] __attribute__((at(0x00007E00))) = {0, 1, 0x05E0}; Что и как должен сделать си-стартап код? Цитата Не понимаете - спросите. Не сочтите за грубость, но чё-то закрадываются сомнения, что вы писали во флэш. В NXP, STM, в PIC везде есть минимальная страница стирания и очень (специально!) мудреный доступ к командам стирания/записи. Минимальные страницы и записи и стирания есть во всех МК с программной флешью которые я знаю, а не тольков этих. И из чего Вы делаете выводы о моих знаниях?? Не понимаю... Вот о Ваших "знаниях" прекрасно видно уже из первого поста. Цитата В общем, вопрос исчерпан, спасибо всем за внимание. Проблема успешно заметена под ковёр Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться