Перейти к содержанию
    

как в winavr сделать так чтоб в прерывании вместо push/pop было st/ld

есть проблема с компилятором WinAVR-20071221 в прерываниях он ставит push/pop, в результате стека не хватает, хочу заменить на st/ld, кто знает как это зделать, перейти на iar нет возможности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть проблема с компилятором WinAVR-20071221 в прерываниях он ставит push/pop, в результате стека не хватает, хочу заменить на st/ld, кто знает как это зделать, перейти на iar нет возможности.

 

Не хотелось бы вас огорчать , но насколько я знаю в иаре тоже в прерываниях push/pop... НУ вот так они организованы....

А что за камень что стэк не помесчается ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть проблема с компилятором WinAVR-20071221 в прерываниях он ставит push/pop, в результате стека не хватает, хочу заменить на st/ld, кто знает как это зделать, перейти на iar нет возможности.

При вызове функций и заходе в прерывания в любом случае адрес возврата сохраняется в стеке.

Также компилятор размещает на стеке локальные переменные и копии регистров, которые портятся во время обработки прерываний.

Так что не используйте в прерывании функций, не определяйте в функциях локальных переменных - и потребление стека уменьшится.

Крайний вариант - писать обработчики прерываний на асме, тогда можно сделать всё что угодно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть проблема с компилятором 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 поможет сократить размер

необходимой памяти ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прямо, никак...

Обходными путями можно, только весь контекст придется ручками сохранять, типа:

void TIMER2_COMP_vect(void) __attribute__((signal)) __attribute__((naked));
void TIMER2_COMP_vect()
{
  {сохраняем контекст}

  {восстанавливаем контекст}
  __asm__ __volatile__("reti"); // выходим
}

 

Только вот непонятен до конца вопрос, как использование st/ld поможет сократить размер

необходимой памяти ?

 

когда сохраняем регистры с помощью st они сохраняются не в стеке, а в памяти выделенной под временные переменные, а вот когда идет push то переменные сохраняются в стек, стек растет и перекрывает собой адресное пространство временных переменных, которые в свою очередь используются в прерывании, в результате стек слетает:( чуть расширю вопрос, есть ли какие нибудь дериктивы чтоб локальные переменные ни при каких условиях не занимали область памяти стека???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

когда сохраняем регистры с помощью st они сохраняются не в стеке, а в памяти выделенной под временные переменные, а вот когда идет push то переменные сохраняются в стек, стек растет и перекрывает собой адресное пространство временных переменных, которые в свою очередь используются в прерывании, в результате стек слетает:( чуть расширю вопрос, есть ли какие нибудь дериктивы чтоб локальные переменные ни при каких условиях не занимали область памяти стека???

 

может быть static поможет?

 

может быть static поможет?

 

или через heap. Сначала new потом обязательно delete.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

когда сохраняем регистры с помощью st они сохраняются не в стеке, а в памяти выделенной под временные переменные, а вот когда идет push то переменные сохраняются в стек, стек растет и перекрывает собой адресное пространство временных переменных,

Вы заблуждаетесь. Временные (локальные) переменные располагаются также в стеке, а вот глобальные лежат по строго фиксированным адресам. Обращаться к стеку можно как с помощью PUSH/POP так и с помощью LD/ST. Судя по всему у Вас просто не хватает стека для нормальной работы программы. Менять PUSH/POP на LD/ST ничего не даст если памяти не хватает. Выход здесь такой - просто увеличить объем стека (сократить количество глобальных переменных, за счет замены их локальными переменными).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы заблуждаетесь. Временные (локальные) переменные располагаются также в стеке, а вот глобальные лежат по строго фиксированным адресам. Обращаться к стеку можно как с помощью PUSH/POP так и с помощью LD/ST. Судя по всему у Вас просто не хватает стека для нормальной работы программы. Менять PUSH/POP на LD/ST ничего не даст если памяти не хватает. Выход здесь такой - просто увеличить объем стека (сократить количество глобальных переменных, за счет замены их локальными переменными).

 

нет, локальные распологаются не в области стека, проверял, проблема то возникает из-за небольшой рекурсии, но если push/pop заменить на st/ld, как было в iar, то все работает, но на iar вернуться нельзя, в том то и проблема, если кто знает директивы компилятору, чтоб push/pop заменить на st/ld то они мне впринципе и нужны, памяти используется 96%, но опятьже из-за небольшой рекурсии есть залезание в стек локальными переменными, к сожаленю логику программы переделывать мне месяц не дадут, сократить объем памяти тоже нет возможности:(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нет, локальные распологаются не в области стека, проверял

А где по вашему они располагаются???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нет, локальные распологаются не в области стека, проверял, проблема то возникает из-за небольшой рекурсии, но если push/pop заменить на st/ld, как было в iar, то все работает

Не понимаю как такое может быть. Если есть рекурсия, то локальные переменные обязательно должны быть в стеке, иначе у тебя будет один комплект переменных на все вызовы. Либо - ты рекурсией называешь что-то не то.

Изменено пользователем 777777

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А где по вашему они располагаются???

Обычно в регистрах. Если их не очень много.

А вот предыдущее содержимое регистров идет в стек.

Изменено пользователем Qwertty

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А где по вашему они располагаются???

 

если считать что стек распологается в sram и локальные и глобальные тамже, то да, спорить не буду, вопрос как ограничить компилятору залезание в область стека, iar это делает, может я тупой, да я привык работать на асме, и там таких проблем нет, ладно вопрос остается открытым, полезу заново перечитывать документацию по компилятору, мож если более внимательнее перечитаю то найду решение, просьба не флудить в теме, если есть решение как заменить push/pop на st/ld при компиляции, то прошу поделиться опытом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

просьба не флудить в теме, если есть решение как заменить push/pop на st/ld при компиляции, то прошу поделиться опытом.

 

Если не флудить - то никак нельзя.

 

А если немного пофлудить, то:

С каким уровнем оптимизации Вы компилируете проэкт?

В какой памяти Вы распологаете строковые переменные и/или таблицы констант?

 

Анатолий.

Изменено пользователем aesok

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все дело IMHO в разных способах организации стека. В ИАР он рганизован программно без использования регистра указателя стека, поэтому там St/Ld, а у вас фактически аппаратно с использованием регистра указателя стека, такова реализация компилятора. Боюсь, что никак эту особенность вам не обойти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если есть решение как заменить push/pop на st/ld при компиляции, то прошу поделиться опытом.

Решение привел выше singlskv.

А в начале обработчика ассемблерной вставкой сохраняйте регистры куда угодно. Только чем это поможет непонятно.

И еще непонятно, как связаны обработчик прерывания и рекурсия. Вы в обработчике используете рекурсивную функцию? Или речь про вложенные прерывания?

 

В какой памяти Вы распологаете строковые переменные

А что, есть варианты? :07:

Изменено пользователем Qwertty

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...