|
|
  |
Вопрос по WinAVR, Как изменить размер стека? |
|
|
|
Sep 17 2008, 06:13
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Freeze Anti @ Sep 17 2008, 08:57)  Хочу попробовать увеличить, но что-то не нашел в манах, как это сделать... В avr-gcc стек один (в отличие от IAR) и указатель стека всегда настраивается на верхушку памяти, тогда как место под неавтоматические переменные выделяется снизу. Таким образом, размер стека автоматически устанавливается на максимально возможный. Убедитесь, что оптимизация включена, просмотрите код, может где-то забыт массив, который уже не нужен. Старайтесь не вызывать функции из обработчиков прерываний (за исключением inline-функций), так как это увеличивает расход стека. Если есть вложенные прерывания - попробуйте обойтись без них. Не используйте оптимизацию -O3, при этом в коде инлайнится всё, до чего компилятор может дотянуться и это тоже может привести к росту использования стека (ненужные inline проскакивают и при -Os - для static-функций, на то есть __attribute__((__noinline__)) )
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 17 2008, 06:20
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(Freeze Anti @ Sep 17 2008, 09:57)  Собственно, сабж... У меня в программе используется достаточно много вложенных if, из которых еще и вызываются функции, плюс еще прерывания используются... Короче, есть предположение, что стека не хватает... Хочу попробовать увеличить, но что-то не нашел в манах, как это сделать... Вложенные if-ы не влияют на увеличение стека. Увеличить его не получится, так как от и так устанавливается на максимум. А вообще, если программа не работает, надо искать причину целенаправленно, а не выдумывать причины самому. Цитата(ReAl @ Sep 17 2008, 10:13)  Старайтесь не вызывать функции из обработчиков прерываний (за исключением inline-функций), так как это увеличивает расход стека. Насколько я знаю, в avr-gcc этого нельзя делать потому, что подпрограмма обработки прерываний сохраняет только те регистры, которые использует сама, а какие регистры использует вызванная функция - она не знает и потому не сохраняет.
|
|
|
|
|
Sep 17 2008, 06:47
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(777777 @ Sep 17 2008, 09:20)  Насколько я знаю, в avr-gcc этого нельзя делать потому, что подпрограмма обработки прерываний сохраняет только те регистры, которые использует сама, а какие регистры использует вызванная функция - она не знает и потому не сохраняет. Она не знает - поэтому сохраняет все, которые не сохранит вызываемая функция (т.е. все, кроме calee-saved). Это и приводит к перерасходу стека: Код extern void foo(void);
ISR(INT1_vect) { foo(); } Код .global __vector_2 .type __vector_2, @function __vector_2: /* prologue: frame size=0 */ push __zero_reg__ push __tmp_reg__ in __tmp_reg__,__SREG__ push __tmp_reg__ clr __zero_reg__ ; а вот регистры с R2 по R17 вызываемая функция обязана по соглашению сохранять сама push r18 push r19 push r20 push r21 push r22 push r23 push r24 push r25 push r26 push r27 push r30 push r31 /* prologue end (size=17) */ rcall foo /* epilogue: frame size=0 */ pop r31 pop r30 pop r27 pop r26 pop r25 pop r24 pop r23 pop r22 pop r21 pop r20 pop r19 pop r18 pop __tmp_reg__ out __SREG__,__tmp_reg__ pop __tmp_reg__ pop __zero_reg__ reti Теперь даже если foo() и использует-то только r25:r24, но сохраняется целая толпа и расход стека растёт. p.s. возможно, в какой-то из версий баг был в этом месте, но меня обошло.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 17 2008, 09:06
|

Гуру
     
Группа: Свой
Сообщений: 3 304
Регистрация: 13-02-07
Из: 55°55′5″ 37°52′16″
Пользователь №: 25 329

|
По теме - на сколько я помню изменить значение стэка в WinAVR можно так: Код __stack=0x123 Теперь стэк начинается с 0x123. Это надо писать по моему в make-файле, поправте если не прав. По умолчанию __stack равен RAMEND.
|
|
|
|
|
Sep 17 2008, 09:59
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Kuzmi4 @ Sep 17 2008, 12:06)  По теме - на сколько я помню изменить значение стэка в WinAVR можно так: Код __stack=0x123 По умолчанию __stack равен RAMEND. Таким образом стек можно только уменьшить. Ну разве что поцеплено внешнее ОЗУ и таким образом направить стек туда, но тогда уж лучше туда вытолкать глобальные массивы типа коммуникационных буферов, а стек оставить в более быстрой внутренней памяти.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|