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

 
 
 
Reply to this topicStart new topic
> Почему в small-модели стеки находятся снизу?, (IAR EW AVR)
Xenia
сообщение Jun 13 2009, 18:15
Сообщение #1


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Почему в small-модели стеки находятся снизу и как это исправить?

Работая с ATtiny2313 я уже привыкла к тому, что стеки (CSTACK и RSTACK) находятся сверху (в старших адресах). Это было очень удобно тем, что в программе можно было явно установить указатель RSTACK'а на самый верх, тем самым, задействуя всю неиспользованную память под стеки. Вручную же рассчитывать размеры стеков крайне неудобно, т.к. CSTACK запрашивают в байтах, а RSTACK в словах. А я не арифмометр, чтобы подбирать эти значения так, чтобы они вписались во весь объем памяти. Тем более что такую операцию мне пришлось бы выполнять каждый раз, когда бы я заводила или удаляла какую-нибудь переменную или изменяла размеры массива. А так, устанавливаешь указатель на вершину памяти и никакой тебе головной боли.
Однако перейдя со временем на МК с большим объемом ОЗУ, пришлось перейти и на модель памяти small. И тут меня ждало неприятное известие о том, что теперь стеки находятся внизу, за ними данные, а пустое пространство сверху. Теперь его уже никак нельзя использовать, кроме как вручную каждый раз изменять размеры стеков в проекте.
В таком расположении стеков я ничуть не виновата - IAR так делает сам. Вот посмотрите на контрольный тест для ATmega8. Этот МК выбран только потому, что допускает обе модели памяти: как tiny, так small. Пишу простейшую программу, содержащую массив данных Buffer, и компилирую ОДИН И ТОТ ЖЕ ПРОЕКТ на tiny и small моделях, переключая в проекте ТОЛЬКО тип модели и не трогая ничего остального.

Код
unsigned char Buffer[70];

C_task main( void )
{
  Buffer[0] = 0;
}

В модели tiny получаю:

Код
SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
=======              =====    =============   ===========     ====  ====  =====
TINY_I               DATA               00000060                     dse    0
TINY_Z               DATA          00000060 - 000000A5          46   rel    0
CSTACK               DATA          000000A6 - 000000B9          14   dse    0
RSTACK               DATA          000000BA - 000000C9          10   dse    0

А в модели small вот это:

Код
SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
=======              =====    =============   ===========     ====  ====  =====
CSTACK               DATA          00000060 - 00000073          14   dse    0
RSTACK               DATA          00000074 - 00000083          10   dse    0
NEAR_I               DATA               00000084                     dse    0
NEAR_Z               DATA          00000084 - 000000C9          46   rel    0

Абсолютно та же самая ситуация со small-моделью во всех остальных моделях МК (проверяла еще и на AT90USB647).

Мой вопрос: Какими соображениями обусловлено такое распределение памяти в small-модели? Можно ли как-то изменить такое распределение памяти и заставить компилятор размещать данные ниже стеков?

Сообщение отредактировал Xenia - Jun 13 2009, 18:22
Go to the top of the page
 
+Quote Post
SSerge
сообщение Jun 13 2009, 19:21
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Разница в .xcl файлах.
Линкер размещает сегменты в памяти в том порядке, в каком они перечислены в директивах -Z(DATA).


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jun 13 2009, 19:38
Сообщение #3


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Xenia, Вы очевидно полагаетесь на конфигурирование Вашего проекта через диалог (General Options->Target->System configuration->Configure system using dialog).
Если хотите держать всё под контролем, конфигурируйте систему через .xcl файл.
Нужный файл нужно скопировать в свой проект из папки /avr/config установленного продукта и указать на него в настройках Linker->Config->Linker command file и править его размещая сегменты как душе угодно.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jun 13 2009, 20:12
Сообщение #4


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(SSerge @ Jun 13 2009, 23:21) *
Разница в .xcl файлах.
Линкер размещает сегменты в памяти в том порядке, в каком они перечислены в директивах -Z(DATA).


Это не так!
Для ATmega8 по умолчанию имеются два файла для конфигурации линкера: lnkm8t.xcl (для tiny-модели) и lnkm8s.xcl (для small-модели). Смотрим конфигурацию для small-модели (файл lnkm8s.xcl):

/* Internal data memory */
-Z(DATA)TINY_I,TINY_Z,TINY_N=60-FF
-Z(DATA)NEAR_I,NEAR_Z=60-45F
-Z(DATA)RSTACK+_..X_RSTACK_SIZE=60-45F
-Z(DATA)CSTACK+_..X_CSTACK_SIZE=60-45F
-Z(DATA)HEAP+_..X_HEAP_SIZE=60-45F
-Z(DATA)IOSTREAM_N#60-45F
-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=60-45F

Как видим, стеки перечислены ПОСЛЕ данных, но, тем не менее, располагаются они в обратном порядке (RSTACK+CSTACK ниже чем NEAR_I+NEAR_Z). Примерно таже последовательность и в файле конфигурации tiny-модели. Если отбросить все то, что к делу не относится (хипы и иостримы), но порядок перечисления сегментов -Z(DATA) для обоих моделей использован одинаковый - память раньше стеков, но результат компиляции получается разный.
Ваше утверждение уже потому не может быть правдой, что в конфигурациях линкера строка RSTACK стоит раньше чем CSTACK, когда как каждому известно, что CSTACK всегда ниже RSTACK'а, т.к. первый растет вверх, а второй вниз.

Сообщение отредактировал Xenia - Jun 13 2009, 20:26
Go to the top of the page
 
+Quote Post
KRS
сообщение Jun 13 2009, 21:12
Сообщение #5


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Xenia @ Jun 14 2009, 00:12) *
RSTACK стоит раньше чем CSTACK, когда как каждому известно, что CSTACK всегда ниже RSTACK'а, т.к. первый растет вверх, а второй вниз.

Это с каких пор CSTACK вверх растет???
Вы листинг смотрели? Там видно сразу куда что растет.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jun 13 2009, 21:57
Сообщение #6


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(KRS @ Jun 14 2009, 01:12) *
Это с каких пор CSTACK вверх растет???
Вы листинг смотрели? Там видно сразу куда что растет.

В tiny-модели вроде бы CSTACK кверху рос. Впрочем, я не твердо в том уверена, поскольку старалась локальные переменные в функциях размещать в мусорных регистрах. Но в какую бы сторону ни рос стек, мой вопрос остается в силе. Я привела явные доказательства того, что в small-модели стеки организуются ниже данных. Об этом однозначно свидетельствует выдержка из map-файла, которую я привела в первом сообщении. Пока мой вопрос о причинах этого явления остается без ответа.

Сообщение отредактировал Xenia - Jun 13 2009, 21:57
Go to the top of the page
 
+Quote Post
KRS
сообщение Jun 13 2009, 22:03
Сообщение #7


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



а вы свой XCL файл писали?
Что то у меня всегда сегменты шли в нужном мне порядке...
попробуйте их тогда в одной строчке перечислить! тогда точно в нужном порядке пойдут!
Go to the top of the page
 
+Quote Post
SSerge
сообщение Jun 13 2009, 22:19
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Проверил на версии 4.12.
Ещё интереснее, при установленой галке General Options->Target->Configure system using dialog(not in .XCL file) директивы размещения сегментов берутся из \avr\src\template\cfg1soim.xcl или \avr\src\template\cfg1toim.xcl.

А при снятой - из \avr\config\lnkm8s.xcl или \avr\config\lnkm8t.xcl.
Это видно в "шапке" в начале map-файла.

При снятии/установке галки положение сегментов меняется, но именно в соответствии с порядком следования -Z директив в этих файлах.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jun 14 2009, 08:02
Сообщение #9


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Xenia @ Jun 14 2009, 00:57) *
Пока мой вопрос о причинах этого явления остается без ответа.

Постараюсь ещё раз.
У Вас было два вопроса: о причинах и соображениях такого распределения и как сделать так как надо.
На первый вопрос Вам ответили, что расположение сегментов описано в xcl файлах. Из чего исходили IARовцы, располагая таким образом сегменты - одному Богу известно. Абсолютно однозначных причин на это нет.
Что касается второго вопроса, то в третьем посте я Вам уже говорил, что нужно сделать. Добавлю только, что если Вы хотите прижать стеки к потолку ОЗУ, то вместо символа "=" надо ставить "#"
Код
-Z(DATA)RSTACK+_..X_RSTACK_SIZE#60-45F
-Z(DATA)CSTACK+_..X_CSTACK_SIZE#60-45F
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jun 14 2009, 14:04
Сообщение #10


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(SSerge @ Jun 14 2009, 02:19) *
Ещё интереснее, при установленой галке General Options->Target->Configure system using dialog(not in .XCL file) директивы размещения сегментов берутся из \avr\src\template\cfg1soim.xcl или \avr\src\template\cfg1toim.xcl.
А при снятой - из \avr\config\lnkm8s.xcl или \avr\config\lnkm8t.xcl.
Это видно в "шапке" в начале map-файла.
При снятии/установке галки положение сегментов меняется, но именно в соответствии с порядком следования -Z директив в этих файлах.


Огромное спасибо! Теперь мне стала абсолютно ясна причина, по которой у меня расстановка сегментов не соответствовала файлу конфигурации lnkm8s.xcl - компилятор брал его из другого файла cfg1soim.xcl, поскольку та галка у меня в проекте стояла.
Стало быть разница в укладке сегментов следует из содержимого файлов конфигурации cfg1soim.xcl и cfg1toim.xcl.

В модели tiny стеки выше tiny-данных:

-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE
-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE
-Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE
-Z(DATA)IOSTREAM_N#_..X_SRAM_TBASE:+_..X_SRAM_TSIZE
-Z(DATA)TINY_HEAP+_..X_TINY_HEAP_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE
-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_RSTACK_BASE-_..X_RSTACK_END
-Z(DATA)NEAR_I,NEAR_Z=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)NEAR_N=_..X_SRAM_BASE-_..X_SRAM_END

А в модели small стеки ниже near-данных:

-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE
-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_CSTACK_BASE-_..X_CSTACK_END
-Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)IOSTREAM_N#_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_RSTACK_BASE-_..X_RSTACK_END
-Z(DATA)NEAR_I,NEAR_Z,NEAR_N=_..X_SRAM_BASE-_..X_SRAM_END

Еще раз спасибо за исчерпывающее разъяснение!

Сообщение отредактировал Xenia - Jun 14 2009, 14:07
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 6th July 2025 - 20:31
Рейтинг@Mail.ru


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