реклама на сайте
подробности

 
 
> STM32F429 + SDRAM + Keil, Расположение переменных в памяти
MiklPolikov
сообщение Dec 3 2015, 14:53
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Есть STM32F429 + SDRAM IS42S16400J-7TLI 64Мбит , проект в Keil.

Возникли вопросы:
1) Можно ли сделать так, что бы обращение к памяти было не через указатель на её адрес, а просто путем инициализации переменной ?
Т.е. что бы в коде декларировалась переменная char x[100000]; а уже компилятор сам размещал её по адресу внешней памяти ?
2) Нужно сообщить компилятору о наличие этой памяти, а для этого адрес и размер памяти нужно указать вот тут (картинка) в строке RAM1 ? И поставить галочку слева ?
А что означает галочка справа no init ?
3) Нужно ли заботится о том, что бы во внешней памяти размещались только большие массивы, а все часто используемые переменные были во внутренней ?
4) Какие ещё тонкости нужно учитывать ?

Заранее спасибо !
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
QuadMan
сообщение May 10 2017, 13:42
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 92
Регистрация: 25-10-05
Пользователь №: 10 069



Подниму тему, никак не могу понять одну вещь.
Использую Keil, ARM Compiler V6.6.

Вот есть у меня внешняя периферия, которая начинается с адреса 0x50000000 к примеру.
Объявляю структуру
Код
volatile __attribute__((section(".ARM.__at_0x50000000"))) SystemRegs  REGS;

Программа загружается во внешнюю память по адресу 0x10000000 и оттуда работает

в scatter файле пишу
Код
LR_IROM1 0x10000000 0x0000C800  {   ; load region size_region
  ER_IROM1 0x10000000 0x0000C800  { ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
    *(.init_array) ; Section .init_array must be placed explicitly,
                   ; otherwise it is shared between two regions, and
                   ; the linker is unable to decide where to place it.  
  }

  RW_IRAM1 0x20000000 UNINIT 0x0008000  { ; RW data
   .ANY (+RW +ZI)
  }

  ER_PERIPHERAL 0x50000000 UNINIT 0x1000
  {
    *(.ARM.__at_0x50000000)
  }
}

Теперь после запуска отладчика, программа валится в MemoryMngFault, судя по всему при отработке функции _decompress системной библиотеки.
Если убрать секцию ER_PERIPHERAL из scatter файла, и в определении переменной REGS, все компилится и запускается нормально, но REGS, естественно, располагается во внутренней памяти.

Отсюда я делаю вывод, что при загрузке компилятор пытается проинициализировать переменную REGS во внешней памяти, хотя доступ к ней еще не настроен, поэтому и валится в HardFault.

Но, ведь я указал, что эта область UNINIT, зачем он вообще туда лезет? И как правильно это дело настроить? Через указатели не очень хочется.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 10 2017, 20:23
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(QuadMan @ May 10 2017, 16:42) *
Но, ведь я указал, что эта область UNINIT, зачем он вообще туда лезет?

UNINIT, но не ZI, например.

Цитата(QuadMan @ May 10 2017, 16:42) *
И как правильно это дело настроить? Через указатели не очень хочется.

Если речь идет о периферии, то правильно будет как раз через указатели.
Go to the top of the page
 
+Quote Post
QuadMan
сообщение May 11 2017, 12:15
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 92
Регистрация: 25-10-05
Пользователь №: 10 069



Цитата(aaarrr @ May 10 2017, 23:23) *
UNINIT, но не ZI, например.


Если речь идет о периферии, то правильно будет как раз через указатели.

Ok, периферию я переделал на указатели, не сложно.

Но у меня есть еще большой массив данных, который я храню во внешней памяти.

Атрибут zero_init в компиляторе версии 6.6 не распознается, хотя это, похоже, именно то, что нужно.
sad.gif((


Go to the top of the page
 
+Quote Post
jcxz
сообщение May 12 2017, 06:34
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(QuadMan @ May 11 2017, 14:15) *
Но у меня есть еще большой массив данных, который я храню во внешней памяти.
Атрибут zero_init в компиляторе версии 6.6 не распознается, хотя это, похоже, именно то, что нужно.
sad.gif((

Я не знаю Кейла, но например в IAR, чтобы переменная не обнулялась си-стартап-кодом, недостаточно ей указать атрибут __no_init. Надо ещё её поместить в соответствующую (отдельную от .bss) секцию и указать компоновщику в его файле конфигурации не инициализировать эту секцию:
в *.cpp: static __no_init int info @ ".eraw";
в *.icf: do not initialize {section .eraw};
Возможно, что в Кейле аналогично.
Я много раз использовал в проектах внешнюю память, размещал в ней и переменные (инициализированные и нет) и код и без каких-то проблем. Точно так же как во внутренней ОЗУ. Правда всё под IAR и CCS.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th August 2025 - 23:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.01424 секунд с 7
ELECTRONIX ©2004-2016