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

Как убрать атрибут [Compressed] для секции Flash?

Отгородил себе флэш для энергонезависимых настроек:

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? Кажется, что дело в нем.

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


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

 Вы уверены, что отключение сжатия поможет? Тогда: в опциях линкера указать

--datacompressor off

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


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

1 час назад, Alex_7211 сказал:

Отгородил себе флэш для энергонезависимых настроек:

uint16_t ID[256] __attribute__((at(0x00007E00))) = {0, 1, 0x05E0};

А const  где?

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


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

3 часа назад, VladislavS сказал:

А const  где?

Если я ставлю const, то сектор меняет атрибут RW на RO и перестает стираться/записываться из программы (!) почему-то. Я пробовал. Если это имеет значение, то проц NXP MKE06Z64VLH4 на ядре M0+. Частичная или полная блокировка записи во флэш задается в startXXX.s и там весь флэш открыт для записи. Дальше копать не стал. Работает как переменная и ладно.

3 часа назад, Палыч сказал:

 Вы уверены, что отключение сжатия поможет? Тогда: в опциях линкера указать

--datacompressor off

Перекомпилировал. "Compressed" исчезло. Кажется это оно. Завтра перешью, проверю. Спасибо вам, добрый человек!

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


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

1 час назад, Alex_7211 сказал:

Работает как переменная и ладно.

Flash как переменная? Барин знает толк в извращениях...

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


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

3 часа назад, Alex_7211 сказал:

Если я ставлю const, то сектор меняет атрибут RW на RO и перестает стираться/записываться из программы (!) почему-то. Я пробовал.

Это вообще не понятно. Такого не должно быть.

Компрессия данных применяется линкером ТОЛЬКО для секций с атрибутом RW. Для RO не применяется. Причем она по-умолчанию включена. Линкер думает, что это ОЗУ и вставляет до main() код декомпрессии и записи туда начальных значений. Т.к. это не ОЗУ, а флеш, то к требуемому результату это не приводит. Но остается вопрос: а почему там не 0хFFFF во всех элементах массива? Значит, перед программированием эта область памяти не стирается, и там остается мусор?

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


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

13 часов назад, Alex_7211 сказал:

Перекомпилировал. "Compressed" исчезло. Кажется это оно. Завтра перешью, проверю. Спасибо вам, добрый человек!

Спасибо Палычу, изгоняющему бесов! Всё работает.

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


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

9 часов назад, Darth Vader сказал:

Компрессия данных применяется линкером ТОЛЬКО для секций с атрибутом RW. Для RO не применяется.

Так я же и пишу, что объявляю массив как переменную, которая получает атрибут RW, несмотря на область Flash. При этом всё работало, за исключением компрессии, которая появилась не сразу и стала портить начальные значения. Почему не 0xFFFF - потому что я инициализирую первые 6 байт при объявлении массива. В настройках программатора стоит "erase full chip".

Когда я, как человек воспитанный, объявлял массив const и он получал RO, то не работало стирание из программы - всегда ошибка. Это были мои вторые грабли при работе с Flash. Первые - в модуле MCM установить Enable Stalling Flash Controller, иначе reset сразу при попытке стирания. Возможно, в этом модуле нужно было что-то еще подшаманить, чтобы const заработал, ХЗ.

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


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

1 час назад, Alex_7211 сказал:

Почему не 0xFFFF - потому что я инициализирую первые 6 байт при объявлении массива. В настройках программатора стоит "erase full chip".

Интересно, а что-же с остальными байтами массива по Вашему мнению?

Я вот к сожалению не знаю способа в си инициализировать только часть массива.  :unknw:

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 находится флешь в вашем МК?).

Это такой тест на количество циклов перезаписи флеша?  :biggrin:   Ну так и тест кривой - надо паттерн-то менять, а то ведь умный загрузчик возьмёт развернёт эту COMPRESSED-секцию инициализации в отдельную память, сравнит с целевой областью памяти и не станет стирать (так как они равны).  :biggrin:

И чем не нравится COMPRESSED? Имхо (если я правильно догадываюсь о его назначении), оно позволяет уменьшить объём секции инициализации переменных, хранящейся во флешь. Ведь у Вас там этот массив инициализируется в основном нулями, и COMPRESSED видимо позволяет линкеру вместо 253 слов нулей записать только пару значение/счётчик_повтора. А убиранием "COMPRESSED" Вы добились только увеличиения секции инициализации данных до полных 256 слов. Тоже не понимаю - зачем???

PS: Советую прислушаться к 

14 часов назад, VladislavS сказал:

Flash как переменная? Барин знает толк в извращениях..

и подумать о том, что поисходит при старте вашей программы в устройстве.

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


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

55 минут назад, jcxz сказал:

чего вы пытаетесь добиться этим?:

Энергонезависимые настройки, которые можно поменять из программы. И новые настройки снова будут энергонезависимыми. Все же так делают, нет?

56 минут назад, jcxz сказал:

Интересно, а что-же с остальными байтами массива по Вашему мнению?

Keil забивает их нулями. Проверено. Но у меня есть более гуманный к Flash вариант и я забиваю все остальные 253 0xFFFF при объявлении.

58 минут назад, jcxz сказал:

Чтобы при каждом включении устройства, оно каждый раз стирало и записывало флешь?

Нет. Кто "оно"? Всё работает ОК. Все данные сохраняются, не переинициализируются первоначальными данными из прошивки, а сохраняются последние записанные. Вы наверное слабо представляете себе перезапись флэш из программы. Тут хрен можно сломать. Компиллятор уж точно ничего не подставит от себя. Слишком чипо-зависимо.

1 час назад, jcxz сказал:

умный загрузчик

не пользуюсь

1 час назад, jcxz сказал:

И чем не нравится COMPRESSED?

Нельзя уменьшать размер секции. 512 байт - минимальная секция для стирания. 

 

1 час назад, jcxz сказал:

и подумать о том, что поисходит при старте

  Прекрасно отдаю себе отчет. Вообще вот просто по шагам и по тактам.

 

1 час назад, jcxz сказал:

Тоже не понимаю - зачем???

Не понимаете - спросите. Не сочтите за грубость, но чё-то закрадываются сомнения, что вы писали во флэш. В NXP, STM, в PIC везде есть минимальная страница стирания и очень (специально!) мудреный доступ к командам стирания/записи.

В общем, вопрос исчерпан, спасибо всем за внимание.

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


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

30 минут назад, Alex_7211 сказал:

Энергонезависимые настройки, которые можно поменять из программы. И новые настройки снова будут энергонезависимыми. Все же так делают, нет?

Пытаются записывать настройки во флешь из стартап-кода? Думаю так делаете только Вы.

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

Цитата

Нет. Кто "оно"? Всё работает ОК. Все данные сохраняются, не переинициализируются первоначальными данными из прошивки, а сохраняются последние записанные.

Оно - это сишный стартап код, которому Вы пытаетесь указать записать данные во флешь, разместив RW-секцию данных с начальной инициализацией во флешь. Чтобы проинициализировать такую секцию, стартап коду как раз надо уметь стирать/писать флешь. Может он это и умеет, может и нет - не знаю, но сильно сомневаюсь.

А раз "данные не переинициализируются первоначальными данными из прошивки", то это и говорит как раз о том, что стартап код не умеет писать во флешь. А просто игнорит ваши инициализационные данные. Просто повезло, что в hard fault при этом не падает. :unknw:

Цитата

Вы наверное слабо представляете себе перезапись флэш из программы. Тут хрен можно сломать. Компиллятор уж точно ничего не подставит от себя. Слишком чипо-зависимо.

Я думаю это Вы слабо представляете мои знания о записи флешь. :russian_ru:

Цитата

не пользуюсь

Под таким "загрузчиком" я имел в виду стандартный сишный стартап.

Цитата

  Прекрасно отдаю себе отчет. Вообще вот просто по шагам и по тактам.

Тогда что по вашему должно происходить при старте программы? при наличии в коде такого:

22 часа назад, Alex_7211 сказал:

uint16_t ID[256] __attribute__((at(0x00007E00))) = {0, 1, 0x05E0};

Что и как должен сделать си-стартап код?

 

Цитата

Не понимаете - спросите. Не сочтите за грубость, но чё-то закрадываются сомнения, что вы писали во флэш. В NXP, STM, в PIC везде есть минимальная страница стирания и очень (специально!) мудреный доступ к командам стирания/записи.

Минимальные страницы и записи и стирания есть во всех МК с программной флешью которые я знаю, а не тольков этих.

И из чего Вы делаете выводы о моих знаниях?? Не понимаю... Вот о Ваших "знаниях" прекрасно видно уже из первого поста.

Цитата

В общем, вопрос исчерпан, спасибо всем за внимание.

Проблема успешно заметена под ковёр  :biggrin:

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


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

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

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

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

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

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

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

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

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

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