Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Стек в IAR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
ILYCHOFF
Не очень давно работаю с IAR. Вот линкер выдал такую ошибку. Что это значит, слишком большой стек? Как тогда правильно определить его размер?


Error[e16]: Segment CSTACK (size: 0x20 align: 0) is too long for segment definition. At least 0x1e more bytes needed. The problem occurred while
processing the segment placement command "-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE", where at the moment
of placement the available memory ranges were "DATA:fe-ff"
Reserved ranges relevant to this placement:
DATA:60-dc TINY_I
DATA:dd-fd TINY_Z
DATA:fe-ff CSTACK
arttab
Какой мк и сколько вы выделили под стек?
ILYCHOFF
МК Мега 16 CSTACK Size 0x20 RSTACK 16

значения по умолчанию

когда первый раз выскочила такая ошибка я изменил CSTACK на 0x10 ошибка пропала все собралось.

а теперь уже меньше ставить не помогает..

Что это за ошибка? Не хватает ОЗУ? Из-за стека?
Andy Mozzhevilov
Сегмент стека не удалось разместить в памяти, то есть ОЗУ не хватает.
Можно урезать стек на 0x1e, тогда влезет.
Вопрос в том, сколько реально нужно.
Abatt
наверно программа у вас очень много ОЗУ использует и на стек места не остается.
ILYCHOFF
Вот я и не могу понять почему не хватает ОЗУ... Я хоть и не так давно пишу на си но все же стараюсь следовать рекомендациям. У меня в коде используются переменные long но они локальные, а как я понимаю локальные переменные уничтожаются при выходе из функции.
В функции я вывожу на LCD некий текст, после выхода из функции он остается в ОЗУ или сохраняется???? Я закоментировал строки с текстом ошибка пропала.
Как тогда с ним поступать писать его во флешь и выводить от туда??
_Bill
Цитата(ILYCHOFF @ Jul 3 2006, 13:32) *
Вот я и не могу понять почему не хватает ОЗУ... Я хоть и не так давно пишу на си но все же стараюсь следовать рекомендациям. У меня в коде используются переменные long но они локальные, а как я понимаю локальные переменные уничтожаются при выходе из функции.
В функции я вывожу на LCD некий текст, после выхода из функции он остается в ОЗУ или сохраняется???? Я закоментировал строки с текстом ошибка пропала.
Как тогда с ним поступать писать его во флешь и выводить от туда??

Вся проблема в том, что все строчные литералы, обычно, размещаются в ОЗУ. Если явно не задать их размещение в памяти программ, то ОЗУ можно занять текстом и под переменные места не останется.
ILYCHOFF
Разместил весь текст во флеш проблемы решились...
Но у меня в проекте используется еще функция sprintf хочу ее заменить на что-нибудь менее прожорливое к ресурсам. Из ICC никак itoa и ltoa не получилось вытащить, может кто поделится исходником, если есть, или алгоритмом. Заранее благодарен.
_Bill
Цитата(ILYCHOFF @ Jul 4 2006, 13:45) *
Разместил весь текст во флеш проблемы решились...
Но у меня в проекте используется еще функция sprintf хочу ее заменить на что-нибудь менее прожорливое к ресурсам. Из ICC никак itoa и ltoa не получилось вытащить, может кто поделится исходником, если есть, или алгоритмом. Заранее благодарен.

Тут файл от IAR, я думаю, этого будет достаточно, если все лишнее убрать.
Нажмите для просмотра прикрепленного файла
Andy_F
А существуют ли какие-то более ли менее чёткие критерии для выбора модели памяти и размеров стеков в IAR, или это чисто эмпирически ? Ну, с моделью памяти понятно, если программа начинает превышать определённый объём - надо переходить к "большей" модели. А стеки ? Может быть, где-то можно почитать рекомендации на этот счёт ?

Просто создаётся ощущение ненадёжности программирования - программа поработала-поработала, и зависла. Стек увеличил (CSTACK) - вроде работает нормально. Но где гарантия, что при выполнении ещё чего-то стек опять не исчерпается ?
_Bill
Цитата(Andy_F @ Aug 3 2006, 10:57) *
Просто создаётся ощущение ненадёжности программирования - программа поработала-поработала, и зависла. Стек увеличил (CSTACK) - вроде работает нормально. Но где гарантия, что при выполнении ещё чего-то стек опять не исчерпается ?

На этапе трансляции компилятор выдает информацию по потребности стека в каждой функции, можно посчитать с учетом вложенности функций. На этапе компоновке линкер выдает сообщение о нехватке стека. Кроме того, использование ОЗУ, размер программных сегментов и их размещение в памяти можно посмотреть в файле карты памяти на выходе линкера. При определении размера стека нужно учитывать потребности стека в процедурах прерывания. Самый худший случай: прерывание в при выполнении функции с наибольшим уровнем вложенности.
А общие рекомендации таковы:
1. не размещать большие наборы данных в стековой памяти. Особенно это относится к массивам или переменным типов long и float. Для них лучше использовать статическую память, использование которой легче контроллировать.
2. не вызывать из процедур прерываний друге функции и делать сами процедуры обработки прерываний по возможности короче. Чем короче функция, тем меньше регистров в ней используется.
Andy_F
Цитата(_Bill @ Aug 3 2006, 12:53) *
На этапе трансляции компилятор выдает информацию по потребности стека в каждой функции, можно посчитать с учетом вложенности функций. На этапе компоновке линкер выдает сообщение о нехватке стека. Кроме того, использование ОЗУ, размер программных сегментов и их размещение в памяти можно посмотреть в файле карты памяти на выходе линкера. При определении размера стека нужно учитывать потребности стека в процедурах прерывания. Самый худший случай: прерывание в при выполнении функции с наибольшим уровнем вложенности.
А общие рекомендации таковы:
1. не размещать большие наборы данных в стековой памяти. Особенно это относится к массивам или переменным типов long и float. Для них лучше использовать статическую память, использование которой легче контроллировать.
2. не вызывать из процедур прерываний друге функции и делать сами процедуры обработки прерываний по возможности короче. Чем короче функция, тем меньше регистров в ней используется.


Спасибо. Будем разбираться...


Цитата(_Bill @ Aug 3 2006, 12:53) *
На этапе трансляции компилятор выдает информацию по потребности стека в каждой функции, можно посчитать с учетом вложенности функций. На этапе компоновке линкер выдает сообщение о нехватке стека. Кроме того, использование ОЗУ, размер программных сегментов и их размещение в памяти можно посмотреть в файле карты памяти на выходе линкера. При определении размера стека нужно учитывать потребности стека в процедурах прерывания. Самый худший случай: прерывание в при выполнении функции с наибольшим уровнем вложенности.
А общие рекомендации таковы:
1. не размещать большие наборы данных в стековой памяти. Особенно это относится к массивам или переменным типов long и float. Для них лучше использовать статическую память, использование которой легче контроллировать.
2. не вызывать из процедур прерываний друге функции и делать сами процедуры обработки прерываний по возможности короче. Чем короче функция, тем меньше регистров в ней используется.


Спасибо, буду разбираться...
zltigo
Цитата(_Bill @ Aug 3 2006, 11:53) *
На этапе компоновке линкер выдает сообщение о нехватке стека.

Увы, линкер принципиально не может ничего сказать о нехватке каких-либо runtime распределяемых областей памяти. Единственно, что линкер может(вынужден) сообщить, это о полном отсутствии сегмента стека.
rezident
Цитата(zltigo @ Aug 4 2006, 01:57) *
Цитата(_Bill @ Aug 3 2006, 11:53) *

На этапе компоновке линкер выдает сообщение о нехватке стека.

Увы, линкер принципиально не может ничего сказать о нехватке каких-либо runtime распределяемых областей памяти. Единственно, что линкер может(вынужден) сообщить, это о полном отсутствии сегмента стека.

Угу. Намедни с этим столкнулся и тоже при использовании sprintf. Надо-то было всего навсего одну переменную float преобразовать к виду x.xx со знаком. А sprintf аж под 80 байт стека отожрала для этого sad.gif И обнаружил я это (наползание стека на данные) лишь в симуляторе, когда пошагово стал смотреть выполнение процедуры, одновременно следя за указателем стека. Сам IAR даже не "мяргнул" про нехватку памяти или о столь большом стеке.
_Bill
Цитата(zltigo @ Aug 3 2006, 22:57) *
Увы, линкер принципиально не может ничего сказать о нехватке каких-либо runtime распределяемых областей памяти. Единственно, что линкер может(вынужден) сообщить, это о полном отсутствии сегмента стека.

Само собой. Линкер выдает сообщение о нехватке памяти, в том числе и стека. Точнее, выдается сообщение о нехватке сегмента под стек. Но это, опять же, тогда, когда вообще не хватает памяти данных (ОЗУ).
junoSynthesizer
позволю себе поднять тему.

люди, подскажите... а то тоже возникли проблемы с нехваткой ОЗУ в АТмеге16. первый раз столкнулся с этим, необходима помощь в понимании.

вопрос первый:
под что идут CSTACK и RSTACK соответственно при работе программы?
насколько я понимаю, RSTACK - исключительно под адреса возврата из функций (может ещё под локальные переменные), а CSTACK под передаваемые в функции параметры?

я никак не могу понять, что куда и зачем мне в памяти размещает иар.

в карте линковщика написано
474 bytes of DATA memory (+ 21 absolute )
при 1 кб доступных. но стоит мне добавить 9-байтовый массив - всё, начинается фигня, как бы я ни крутил параметры стека.

TINY_I DATA 00000060 Predefined 0
TINY_Z DATA 00000060 - 000000C0 61 Relative 0
CSTACK DATA 000000C1 - 000000F5 35 Predefined 0
RSTACK DATA 000000F6 - 00000239 144 Predefined 0
помогите так же разобраться с этим. под что идёт куча?

у меня максимальная вложенность функций равна 5. но при размере RSTACK меньше 140 еначинаются зависания...
совсем запутался.
да, ещё: в программе не используется ничего больше uint. максимально объёмные передаваемые данные в функцию - в сумме не больше 4х байт.
IgorKossak
junoSynthesizer, судя по листингу сегментов, Вы выбрали модель памяти tiny. Выберите small и будет Вам счастье.
Когда говорите о сообщениях компилятора\линкера, приводите текст сообщения.
Куча (если речь идёт о heap) выделяется только тогда, когда в программе есть команды, к ней обращающиеся.
junoSynthesizer
к куче обращаются команды malloc и иже с ней? а если я их не использую? тогда мне вообще куча не нужна получается?

и таки-да, Вы правы, у меня стоит модель тини. попробую сделать смолл. спасибо за совет.


-----------------
спасибо, действительно всё дело было в модели памяти. совсем забыл что при тини пхается и стек и данные в одну область (по х86 асму так вроде)

ещё попросматривал листинги - и увидел, что стек данных так же необходим для сохранения регистров ОН.
IgorKossak
Цитата(junoSynthesizer @ Nov 28 2006, 18:03) *
к куче обращаются команды malloc и иже с ней? а если я их не использую? тогда мне вообще куча не нужна получается?

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