|
Размещение переменой по заданному адресу и ее значение после ресета |
|
|
|
Aug 2 2017, 18:46
|
Местный
  
Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207

|
Представленный код инкрементит переменную между ресетами, но есь вопросы по надежности, а именно - не затрется ли переменная. Размещение переменой по заданному адресу означает что под нее будет выделено место в памяти, заданное адресом? Или это просто будет ссылка на заданный адрес - а что там - неизвестно? STM32F2, IAR Код #include "stm32f2xx.h"
static __no_init __root uint32_t flag @0x20000000;
int main(void) { flag++; NVIC_SystemReset(); } Вот разница в .map файлах. Слева - с переменной flag, справа - без:
|
|
|
|
|
Aug 2 2017, 19:25
|

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

|
QUOTE (turnon @ Aug 2 2017, 21:46)  а именно - не затрется ли переменная. CODE __no_init "У нас принято джентльменам верить на слово" ("Чокнутые").
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Aug 2 2017, 20:41
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Сергей Борщ @ Aug 2 2017, 22:25)  "У нас принято джентльменам верить на слово" ("Чокнутые"). Джентльменам может и да, а вот компоновщику нужно указывать явно - что и куда грузить и инитить или нет. А у автора - как повезёт прописано в .icf-файле: если на данный адрес не смаппирована ни одна инициализируемая секция - повезло, а иначе - ну тут уж видно не судьба Вобщем - лучше не пользоваться такими конструкциями, а написать: static __no_init __root uint32_t flag @ ".моя_секция"; а уж в .icf прописать куда эту ".моя_секция" компоновать. И там-же - указать, что её не нужно инитить. А то ведь можно даже и переменные __no_init лёгким мановением .icf-файла сделать инициализируемыми  PS: И кто сказал что IAR - джентльмен?
|
|
|
|
|
Aug 3 2017, 09:09
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(jcxz @ Aug 2 2017, 23:41)  А у автора - как повезёт прописано в .icf-файле: если на данный адрес не смаппирована ни одна инициализируемая секция - повезло, а иначе - ну тут уж видно не судьба  Это где-нибудь в документации написано? Потому что я видел только объяснения "хотите разместить что-нибудь по фиксированному адресу - используйте секции или синтаксис @адрес ". И, с моей точки зрения, второй способ удобнее - всё в одном месте, не размазано по исходнику и скрипту линкера.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Aug 3 2017, 19:30
|
Знающий
   
Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088

|
Цитата(jcxz @ Aug 3 2017, 19:39)  Что именно описано? У автора в коде написано, что он помещает переменную по адресу 0x20000000. А что находится по этому адресу - известно только .icf файлу. Там может быть что-то, а может и не быть. Нет. Если есть прямая директива разместить переменную по фиксированному адресу, то линкер её там и разместит, все остальные переменные лягут по другим адресам, никакого "затирания" не произойдет. В противном случае смысл в этой директиве напрочь отпадает.
--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
|
|
|
|
|
Aug 3 2017, 20:07
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Отлично. Берём другого автора. https://www.iar.com/support/tech-notes/comp...ecific-address/Они делают то же самое, и не говорят, что между двумя способами указания адреса есть какая-то разница. Цитата(jcxz @ Aug 3 2017, 19:39)  А что находится по этому адресу - известно только .icf файлу. Там может быть что-то, а может и не быть. А вот это неправда. Что находится по этому адресу, известно линкеру. Один из способов сообщить это линкеру - icf-скрипт. Другой - прагмы и IAR'овские расширения языка си непосредственно в исходнике. Более того, достаточно прочитать первое сообщение темы - там отчётливо видно, как этот флажок расположен именно в том месте, какое и подразумевалось при объявлении. И что стек автоматически смещается, тоже видно. Т.е. линкер эту область видит. Ставим галочку. Что будет, если линкер не сможет растолкать bss (zero-init), data (non-zero-init), стек и эти секции в области памяти - надо проверять. Но в то, что без каких-то ошибок они перекроют друг друга, я не верю. И аргументов от Вас никаких не услышал. Цитата(jcxz @ Aug 3 2017, 19:39)  Вот именно удобно когда всё размещение в памяти описано в одном месте. У IAR это место - .icf-файл. Чувства верующих я, пожалуй, обсуждать не буду.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Aug 5 2017, 10:25
|
Местный
  
Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207

|
Цитата(HardEgor @ Aug 3 2017, 12:00)  Если нет батарейки, то делаю питание BKP от конденсатора с диодной развязкой - надолго хватает. Потребление RTC - 5 uA. Если питание пропадет на сутки, чтобы RTC не сбросился (снижение напряжение с 3.3 до 2.3В) понадобится конденсатор 432000 uF (!). Конденсатор мелкие тоже ставлю, но исключительно чтобы не было сброса при заменен батарейки или при дребезге контактов в держателе батарейки. Цитата(esaulenka @ Aug 3 2017, 23:07)  А вот это неправда. Что находится по этому адресу, известно линкеру. Один из способов сообщить это линкеру - icf-скрипт. Другой - прагмы и IAR'овские расширения языка си непосредственно в исходнике. Более того, достаточно прочитать первое сообщение темы - там отчётливо видно, как этот флажок расположен именно в том месте, какое и подразумевалось при объявлении. И что стек автоматически смещается, тоже видно. Т.е. линкер эту область видит. Ставим галочку. Значит таки выделяется место под переменную и не надо ничего прописывать в .icf файле. Это обнадеживает. Цитата(esaulenka @ Aug 3 2017, 23:07)  Что будет, если линкер не сможет растолкать bss (zero-init), data (non-zero-init), стек и эти секции в области памяти - надо проверять. Вот тут не понял, расшифруйте пожалуйста для чайника.
|
|
|
|
|
Aug 5 2017, 21:24
|
Местный
  
Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207

|
Цитата(jcxz @ Aug 5 2017, 13:30)  А зачем нужно это инкрементирование переменной? Возможно есть решения получше, которые Вы не замечаете. Как флаг для бутлоадера. В обычном режиме работы бутлоадер сразу запускает основную прошивку, а если есть флаг - то ожидает загрузки новой прошивки по USB.
|
|
|
|
|
Aug 6 2017, 08:08
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(turnon @ Aug 6 2017, 00:24)  Как флаг для бутлоадера. В обычном режиме работы бутлоадер сразу запускает основную прошивку, а если есть флаг - то ожидает загрузки новой прошивки по USB. Как я и думал.... Вы смотрите совсем не туда. __no_init тут не нужен. Как не нужен и инкремент. __no_init для этого адреса должно быть в бутлоадере. Общий алгоритм таков: В бутлоадере объявляете этот адрес: __no_init char flag @ ...;при старте бутлоадера проверяете сначала флаг причины перезагрузки МК (искать где он нужно в даташите), если сброс был не по причине внутреннего WDT - передаёте управление в основную прогу. Если причина == внутренний WDT и flag != 0 - прошиваете прошивку и flag = 0. В основной программе объявляете: char flag @ ...;А когда нужно обновить прошивку делаете flag = 1 и вызываете срабатывание внутреннего WDT. Всё. PS: И я бы лучше указал имя определённой секции (в тех местах где ...), а не абсолютный адрес. А эту секцию в .icf смаппировал на нужный адрес. И в основной программе и в бутлоадере.
|
|
|
|
|
Aug 6 2017, 09:18
|
Местный
  
Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207

|
Цитата(jcxz @ Aug 6 2017, 11:08)  Вы смотрите совсем не туда. __no_init тут не нужен. Как не нужен и инкремент. __no_init для этого адреса должно быть в бутлоадере. Инкремент я привел для примера. В реальности там флаг, примерно как вы и описали (спасибо за подробный пример). К тому же флаг "подписан" контрольной суммой. Самое важное - что линкер под это выделяет место и что с очередной прошивкой там не окажется случайно не то что ожидаемо.
|
|
|
|
|
Aug 6 2017, 21:16
|
Местный
  
Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207

|
Цитата(HardEgor @ Aug 5 2017, 22:06)  Какие сутки? Вы же писали про ресеты, а не выключение питания. Если всё-таки выключение питания, то либо ставить батарейку, либо писать надо во флеш. А разве батарейка нужна только для BkpSram? Часы же сбросятся. Даже и не представляю, какой сценарий использования без батарейки, но с конденсатором на Vbat.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|