Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Keil. __main обнуляет переменные в Backup SRAM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > Keil
ViKo
Жил-был проект, функция SystemInit была самодельная, задавала частоту PLL и от нее частоты шин. Дальше выполнялась __main, задавала переменные, и переходила к Main.
Решил я добавить в SystemInit инициализацию FSMC (контроллера внешней памяти). Не могу вспомнить, зачем. Вроде, что-то не инициализировалось. [Кстати, стандартная SystemInit тоже так делает.] Заодно и всю остальную периферию инициализировал. До выполнения __main. И теперь эта __main очищает мои переменные, отвечающие за режимы работы прибора, лежащие во внутренней Backup SRAM. Предполагаю, что раньше она просто не могла добраться до этих переменных.
Что наблюдаю в отладчике: Жму Reset - переменные заполнены абракадаброй, но это не настоящее их содержимое, просто доступа нет. После выполнения SystemInit читается их реальное значение, бывшее до сброса. После выполнения __main все эти переменные обнуляются!
Вопрос - что, так и должно быть? И раньше не обнулялись переменные только оттого, что __main не могла до них добраться? В исходниках переменные описаны с атрибутами, в скаттере секции описаны, переменные положены, куда положено ( biggrin.gif )... Типа, вот так:
volatile uint32_t Signature __attribute((section("backup")));

RW_IRAM2 0x40024000 UNINIT 0x00001000 { ; Backup RAM
Main.o (backup)
}
Да, имею вариант вернуться к прежней SystemInit. Но для чего-то мне же понадобилось инициализировать контроллер внешней памяти до __main...

Как заставить Keil не инициализировать избранные глобальные переменные?
ViKo
Так и есть. Задал остановку МК при записи к переменной в BackupRAM. Увидел в __main очистку своих переменных:
Код
0x0800AB14 C808      LDM      r0!,{r3}
0x0800AB16 1F12      SUBS     r2,r2,#4
0x0800AB18 C108      STM      r1!,{r3}
0x0800AB1A 2A00      CMP      r2,#0x00
0x0800AB1C D1FA      BNE      0x0800AB14

Остановился при r1 = 0x40024008, r3 = 0, r2 = 0x38.
aaarrr
Странно, UNINIT у меня работал корректно. И это не очистка, а копирование.
ViKo
Цитата(aaarrr @ Apr 6 2015, 10:43) *
Странно, UNINIT у меня работал корректно. И это не очистка, а копирование.

Копирование. Нуля {r3}. rolleyes.gif По 4 байта.
У меня тоже работало. Или казалось, что работает. Пока не перенес инициализацию BackupRAM в SystemInit.
aaarrr
Цитата(ViKo @ Apr 6 2015, 10:50) *
Копирование. Нуля. rolleyes.gif Побайтно.

Пословно sm.gif Ну а все же, куда R0 указывает?
ViKo
Цитата(aaarrr @ Apr 6 2015, 10:52) *
Пословно sm.gif Ну а все же, куда R0 указывает?

Да, пословно. R0 = 0x08016114, чисто данные во флэш. ~56 нулевых байтов. Вся моя управляющая структура, надо думать.
aaarrr
Вот копирование меня и смущает: структура в Backup RAM по логике должна быть ZI, а не RW. Можете map-файл привести?
ViKo
Код
    Signature                                0x40024000   Data           4  siluet_main.o(backup)
    Ctrl                                     0x40024004   Data          44  siluet_main.o(backup)

Execution Region RW_IRAM2 (Base: 0x40024000, Size: 0x00000040, Max: 0x00001000, ABSOLUTE, UNINIT)

    Base Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x40024000   0x00000004   Data   RW         3116    backup              siluet_main.o
    0x40024004   0x0000002c   Data   RW         3117    backup              siluet_main.o
    0x40024030   0x00000010   Data   RW         3118    backup              siluet_main.o

Я к этой структуре Ctrl обращаюсь постоянно в процессе работы, читаю, изменяю...
aaarrr
А как она объявлена, структура эта?
ViKo
Там структура из структур. Атрибут - только общий, секция. Может, no_init надо? ищу по документации на линкер. _DECL задает extern, если надо.
Код
typedef struct {
  uint8_t    Filt    : 2;
  ...
  uint8_t    dummy2    : 2;
} Acqu_t;

typedef struct {
  Acqu_t Acqu;            // 2 (1)
  ...
  Curs_t Curs;            // 8 (2)
  uint32_t Crc;            // 4
} Ctrl_t;

_DECL Ctrl_t Ctrl __attribute((section("backup")));


Не в структурах дело. Есть простая переменная Signature (начальная версия работы с Backup), она также обнуляется.
_DECL volatile uint32_t Signature __attribute((section("backup")));
aaarrr
Надо разбираться, почему они получили атрибут RW вместо ZI.
Dr.Alex
Если в ИАРе, добавьте __no_init и наверняка проблема решится.

Тьфу, это ж кейл :-)))))) Но наверняка такой квалификатор должен быть..
ViKo
Цитата(aaarrr @ Apr 6 2015, 11:59) *
Надо разбираться, почему они получили атрибут RW вместо ZI.

Если в map написано
Код
Execution Region RW_IRAM2 (Base: 0x40024000, Size: 0x00000040, Max: 0x00001000, ABSOLUTE, UNINIT)

разве это не говорит, что инициализации быть не должно?
aaarrr
Попробуйте это.

Цитата(ViKo @ Apr 6 2015, 12:29) *
Если в map написано
Код
Execution Region RW_IRAM2 (Base: 0x40024000, Size: 0x00000040, Max: 0x00001000, ABSOLUTE, UNINIT)

разве это не говорит, что инициализации быть не должно?

Не-инициализации подлежат только ZI-данные, но не RW.
ViKo
Я вже попробовав ось таке. Помогло. Спасибо! У вас тот же совет.
Я йопнусь с этого Кейла. rolleyes.gif

Цитата(Dr.Alex @ Apr 6 2015, 12:25) *
Если в ИАРе, добавьте __no_init и наверняка проблема решится.
Тьфу, это ж кейл :-)))))) Но наверняка такой квалификатор должен быть..

zero_init, и кто бы мог догадаться? Помнится, сталкивался с неким подобным.
aaarrr
Цитата(ViKo @ Apr 6 2015, 12:41) *
zero_init, и кто бы мог догадаться? Помнится, сталкивался с неким подобным.

Я сталкивался и с вещами похуже. Например, за счет оптимизации код из RAM оказывался перенесенным во флеш с полным игнорированием атрибутов секций. Просто оптимизатор инлайнил код с потерей атрибутов.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.