|
как в winavr сделать так чтоб в прерывании вместо push/pop было st/ld, ... |
|
|
|
May 20 2008, 07:06
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 11-03-08
Пользователь №: 35 811

|
есть проблема с компилятором WinAVR-20071221 в прерываниях он ставит push/pop, в результате стека не хватает, хочу заменить на st/ld, кто знает как это зделать, перейти на iar нет возможности.
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 24)
|
May 20 2008, 08:03
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Kibi @ May 20 2008, 10:06)  есть проблема с компилятором WinAVR-20071221 в прерываниях он ставит push/pop, в результате стека не хватает, хочу заменить на st/ld, кто знает как это зделать, перейти на iar нет возможности. При вызове функций и заходе в прерывания в любом случае адрес возврата сохраняется в стеке. Также компилятор размещает на стеке локальные переменные и копии регистров, которые портятся во время обработки прерываний. Так что не используйте в прерывании функций, не определяйте в функциях локальных переменных - и потребление стека уменьшится. Крайний вариант - писать обработчики прерываний на асме, тогда можно сделать всё что угодно.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
May 20 2008, 08:08
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Kibi @ May 20 2008, 11:06)  есть проблема с компилятором WinAVR-20071221 в прерываниях он ставит push/pop, в результате стека не хватает, хочу заменить на st/ld, кто знает как это зделать, перейти на iar нет возможности. Прямо, никак... Обходными путями можно, только весь контекст придется ручками сохранять, типа: Код void TIMER2_COMP_vect(void) __attribute__((signal)) __attribute__((naked)); void TIMER2_COMP_vect() { {сохраняем контекст}
{восстанавливаем контекст} __asm__ __volatile__("reti"); // выходим } Только вот непонятен до конца вопрос, как использование st/ld поможет сократить размер необходимой памяти ?
|
|
|
|
|
May 20 2008, 09:50
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 11-03-08
Пользователь №: 35 811

|
Цитата(singlskv @ May 20 2008, 12:08)  Прямо, никак... Обходными путями можно, только весь контекст придется ручками сохранять, типа: Код void TIMER2_COMP_vect(void) __attribute__((signal)) __attribute__((naked)); void TIMER2_COMP_vect() { {сохраняем контекст}
{восстанавливаем контекст} __asm__ __volatile__("reti"); // выходим } Только вот непонятен до конца вопрос, как использование st/ld поможет сократить размер необходимой памяти ? когда сохраняем регистры с помощью st они сохраняются не в стеке, а в памяти выделенной под временные переменные, а вот когда идет push то переменные сохраняются в стек, стек растет и перекрывает собой адресное пространство временных переменных, которые в свою очередь используются в прерывании, в результате стек слетает  чуть расширю вопрос, есть ли какие нибудь дериктивы чтоб локальные переменные ни при каких условиях не занимали область памяти стека???
|
|
|
|
|
May 20 2008, 10:01
|
Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782

|
Цитата(Kibi @ May 20 2008, 13:50)  когда сохраняем регистры с помощью st они сохраняются не в стеке, а в памяти выделенной под временные переменные, а вот когда идет push то переменные сохраняются в стек, стек растет и перекрывает собой адресное пространство временных переменных, которые в свою очередь используются в прерывании, в результате стек слетает  чуть расширю вопрос, есть ли какие нибудь дериктивы чтоб локальные переменные ни при каких условиях не занимали область памяти стека??? может быть static поможет? Цитата(VladimirYU @ May 20 2008, 13:58)  может быть static поможет? или через heap. Сначала new потом обязательно delete.
|
|
|
|
|
May 20 2008, 10:29
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 11-03-08
Пользователь №: 35 811

|
Цитата(defunct @ May 20 2008, 14:04)  Вы заблуждаетесь. Временные (локальные) переменные располагаются также в стеке, а вот глобальные лежат по строго фиксированным адресам. Обращаться к стеку можно как с помощью PUSH/POP так и с помощью LD/ST. Судя по всему у Вас просто не хватает стека для нормальной работы программы. Менять PUSH/POP на LD/ST ничего не даст если памяти не хватает. Выход здесь такой - просто увеличить объем стека (сократить количество глобальных переменных, за счет замены их локальными переменными). нет, локальные распологаются не в области стека, проверял, проблема то возникает из-за небольшой рекурсии, но если push/pop заменить на st/ld, как было в iar, то все работает, но на iar вернуться нельзя, в том то и проблема, если кто знает директивы компилятору, чтоб push/pop заменить на st/ld то они мне впринципе и нужны, памяти используется 96%, но опятьже из-за небольшой рекурсии есть залезание в стек локальными переменными, к сожаленю логику программы переделывать мне месяц не дадут, сократить объем памяти тоже нет возможности:(
|
|
|
|
|
May 20 2008, 10:53
|

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

|
Цитата(Kibi @ May 20 2008, 14:29)  нет, локальные распологаются не в области стека, проверял, проблема то возникает из-за небольшой рекурсии, но если push/pop заменить на st/ld, как было в iar, то все работает Не понимаю как такое может быть. Если есть рекурсия, то локальные переменные обязательно должны быть в стеке, иначе у тебя будет один комплект переменных на все вызовы. Либо - ты рекурсией называешь что-то не то.
Сообщение отредактировал 777777 - May 20 2008, 10:53
|
|
|
|
|
May 20 2008, 10:54
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(Непомнящий Евгений @ May 20 2008, 14:47)  А где по вашему они располагаются??? Обычно в регистрах. Если их не очень много. А вот предыдущее содержимое регистров идет в стек.
Сообщение отредактировал Qwertty - May 20 2008, 10:55
|
|
|
|
|
May 20 2008, 10:59
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 11-03-08
Пользователь №: 35 811

|
Цитата(Непомнящий Евгений @ May 20 2008, 14:47)  А где по вашему они располагаются??? если считать что стек распологается в sram и локальные и глобальные тамже, то да, спорить не буду, вопрос как ограничить компилятору залезание в область стека, iar это делает, может я тупой, да я привык работать на асме, и там таких проблем нет, ладно вопрос остается открытым, полезу заново перечитывать документацию по компилятору, мож если более внимательнее перечитаю то найду решение, просьба не флудить в теме, если есть решение как заменить push/pop на st/ld при компиляции, то прошу поделиться опытом.
|
|
|
|
|
May 20 2008, 11:04
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Kibi @ May 20 2008, 14:59)  просьба не флудить в теме, если есть решение как заменить push/pop на st/ld при компиляции, то прошу поделиться опытом. Если не флудить - то никак нельзя. А если немного пофлудить, то: С каким уровнем оптимизации Вы компилируете проэкт? В какой памяти Вы распологаете строковые переменные и/или таблицы констант? Анатолий.
Сообщение отредактировал aesok - May 20 2008, 11:05
|
|
|
|
|
May 20 2008, 11:33
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(Kibi @ May 20 2008, 14:59)  если есть решение как заменить push/pop на st/ld при компиляции, то прошу поделиться опытом. Решение привел выше singlskv. А в начале обработчика ассемблерной вставкой сохраняйте регистры куда угодно. Только чем это поможет непонятно. И еще непонятно, как связаны обработчик прерывания и рекурсия. Вы в обработчике используете рекурсивную функцию? Или речь про вложенные прерывания? Цитата(aesok @ May 20 2008, 15:04)  В какой памяти Вы распологаете строковые переменные А что, есть варианты?
Сообщение отредактировал Qwertty - May 20 2008, 11:31
|
|
|
|
|
May 20 2008, 11:44
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 11-03-08
Пользователь №: 35 811

|
Цитата(VladimirYU @ May 20 2008, 15:25)  Все дело IMHO в разных способах организации стека. В ИАР он рганизован программно без использования регистра указателя стека, поэтому там St/Ld, а у вас фактически аппаратно с использованием регистра указателя стека, такова реализация компилятора. Боюсь, что никак эту особенность вам не обойти. думаю что да, но вопрос остается открытым, как сказать компилятору не ставить push/pop
|
|
|
|
|
May 20 2008, 11:47
|
Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782

|
Цитата(Qwertty @ May 20 2008, 15:33)  Решение привел выше singlskv. А в начале обработчика ассемблерной вставкой сохраняйте регистры куда угодно. Только чем это поможет непонятно. Реализуемый, но жостаточно рискованный способ, можно задеть, например, глобальные переменные или static. Данный подход это первый шаг к откату на asm. Искать выход нужно в организации программы в целом.
|
|
|
|
|
May 20 2008, 15:57
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Qwertty @ May 20 2008, 15:33)  Цитата В какой памяти Вы распологаете строковые переменные А что, есть варианты?  Неправильно выразился... стороковые константы? Анатолий.
Сообщение отредактировал aesok - May 20 2008, 16:02
|
|
|
|
|
May 20 2008, 18:37
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Kibi @ May 20 2008, 15:44)  думаю что да, но вопрос остается открытым, как сказать компилятору не ставить push/pop Думаю что искать это Вы будете очень долго... Вам вроде уже сказали что нет такой возможности, хотя повторое чтение мануалов конечно еще никому не мешало  Ну а если хотите конкретной помощи, тады код в студию....
|
|
|
|
|
Aug 17 2008, 02:41
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Kibi @ May 20 2008, 13:29)  нет, локальные распологаются не в области стека, проверял, проблема то возникает из-за небольшой рекурсии, но если push/pop заменить на st/ld, как было в iar, то все работает, но на iar вернуться нельзя, в том то и проблема, если кто знает директивы компилятору, чтоб push/pop заменить на st/ld то они мне впринципе и нужны, памяти используется 96%, но опятьже из-за небольшой рекурсии есть залезание в стек локальными переменными, к сожаленю логику программы переделывать мне месяц не дадут, сократить объем памяти тоже нет возможности  Плохо проверяли. 1. Локальные переменные всегда располагаются в стеке если не помещаются в регистрах. 2. В IAR два стека, стек данных CSTACK, и стек возвратов RSTACK. И в IAR можно вручную задать их объем, т.о. память под стек заданного объема будет жестко резервирована и будет учитываться при подсчете занимаемой памяти. 3. В WinAVR есть один общий стек ничинающийся с RAMEND ничем не ограниченный снизу (память не резервируется и соответственно стек не учитывается при подсчете занятой памяти). Вы должны сами заботиться о том чтобы стека хватало. Если у вас используется 96% памяти, то значит под стек у вас осталось всего 4%. Умножте количество памяти вашего МК на 0.04 и будет вам число в байтах отведенное под стек в вашей программе. Учтите что для входа в прерывание нужно хотя бы 35 байт RAM + память на вызовы функций + память под локальные переменные. Меньше 256 байт стека, я считаю кощунством.
|
|
|
|
|
Aug 17 2008, 10:16
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Совершенно согласен defunct. с Я бы добавил ещё следующее. В IAR сумма стеков примерно будет равна с той же программе (С учётом эффективности компиляторов).
Таким образом нельзя говорить о вариантах реализации стека PUSH/STD, а можно говорить лишь о недостаточности памяти в целом. Либо о вашем непонимании. Вы поймите если переменная должна оказаться в стеке, то не имеет значения каким образом и в какой именно стек она будет положена! Главное, что она займёт место в памяти.
Другое дело - объявление переменных и параметров. Это может сказаться на эффективности и объёме занимаемой памяти. Например при увеличении числа параметров передаваемом в ф-цию, вероятнее всего у вас увеличится объём занимаемой памяти (стека). Если в рекурсивной ф-ции вы объявите локальную переменную, то она будет размещена на стеке, а если вы её объявите static, то будет создан лишь один экземпляр переменной в памяти (Правда надо осмыслить логику работы).
Я бы вообще попытался бы отказаться от рекурсии. Например в пользу бинарного перебора либо дерева. Очень неэффективна рекурсия в большенстве своём.
|
|
|
|
|
Aug 17 2008, 19:09
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(SasaVitebsk @ Aug 17 2008, 14:16)  Если в рекурсивной ф-ции вы объявите локальную переменную, то она будет размещена на стеке, а если вы её объявите static, то будет создан лишь один экземпляр переменной в памяти (Правда надо осмыслить логику работы). А чего осмысливать - рекурсивная функция должна быть реентерабельной, т.е. никаких static-ов в ней быть не должно.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|