Xenia 42 13 июня, 2009 Опубликовано 13 июня, 2009 (изменено) · Жалоба Почему в 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-модели? Можно ли как-то изменить такое распределение памяти и заставить компилятор размещать данные ниже стеков? Изменено 13 июня, 2009 пользователем Xenia Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 13 июня, 2009 Опубликовано 13 июня, 2009 · Жалоба Разница в .xcl файлах. Линкер размещает сегменты в памяти в том порядке, в каком они перечислены в директивах -Z(DATA). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 13 июня, 2009 Опубликовано 13 июня, 2009 · Жалоба Xenia, Вы очевидно полагаетесь на конфигурирование Вашего проекта через диалог (General Options->Target->System configuration->Configure system using dialog). Если хотите держать всё под контролем, конфигурируйте систему через .xcl файл. Нужный файл нужно скопировать в свой проект из папки /avr/config установленного продукта и указать на него в настройках Linker->Config->Linker command file и править его размещая сегменты как душе угодно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 42 13 июня, 2009 Опубликовано 13 июня, 2009 (изменено) · Жалоба Разница в .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'а, т.к. первый растет вверх, а второй вниз. Изменено 13 июня, 2009 пользователем Xenia Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 13 июня, 2009 Опубликовано 13 июня, 2009 · Жалоба RSTACK стоит раньше чем CSTACK, когда как каждому известно, что CSTACK всегда ниже RSTACK'а, т.к. первый растет вверх, а второй вниз. Это с каких пор CSTACK вверх растет??? Вы листинг смотрели? Там видно сразу куда что растет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 42 13 июня, 2009 Опубликовано 13 июня, 2009 (изменено) · Жалоба Это с каких пор CSTACK вверх растет??? Вы листинг смотрели? Там видно сразу куда что растет. В tiny-модели вроде бы CSTACK кверху рос. Впрочем, я не твердо в том уверена, поскольку старалась локальные переменные в функциях размещать в мусорных регистрах. Но в какую бы сторону ни рос стек, мой вопрос остается в силе. Я привела явные доказательства того, что в small-модели стеки организуются ниже данных. Об этом однозначно свидетельствует выдержка из map-файла, которую я привела в первом сообщении. Пока мой вопрос о причинах этого явления остается без ответа. Изменено 13 июня, 2009 пользователем Xenia Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 13 июня, 2009 Опубликовано 13 июня, 2009 · Жалоба а вы свой XCL файл писали? Что то у меня всегда сегменты шли в нужном мне порядке... попробуйте их тогда в одной строчке перечислить! тогда точно в нужном порядке пойдут! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 13 июня, 2009 Опубликовано 13 июня, 2009 · Жалоба Проверил на версии 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 директив в этих файлах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 14 июня, 2009 Опубликовано 14 июня, 2009 · Жалоба Пока мой вопрос о причинах этого явления остается без ответа. Постараюсь ещё раз. У Вас было два вопроса: о причинах и соображениях такого распределения и как сделать так как надо. На первый вопрос Вам ответили, что расположение сегментов описано в xcl файлах. Из чего исходили IARовцы, располагая таким образом сегменты - одному Богу известно. Абсолютно однозначных причин на это нет. Что касается второго вопроса, то в третьем посте я Вам уже говорил, что нужно сделать. Добавлю только, что если Вы хотите прижать стеки к потолку ОЗУ, то вместо символа "=" надо ставить "#" -Z(DATA)RSTACK+_..X_RSTACK_SIZE#60-45F -Z(DATA)CSTACK+_..X_CSTACK_SIZE#60-45F Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 42 14 июня, 2009 Опубликовано 14 июня, 2009 (изменено) · Жалоба Ещё интереснее, при установленой галке 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 Еще раз спасибо за исчерпывающее разъяснение! Изменено 14 июня, 2009 пользователем Xenia Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться