реклама на сайте
подробности

 
 
> Оптимизация прерываний, Прошу совета
Dmitro25
сообщение Mar 31 2010, 05:47
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



Здравствуйте.
Пишу проект на IAR for AVR.
Возникло желание посмотреть, какой код формирует компилятор для прерываний. Оказалось, что в начале процедуры прерывания сохраняется в data-stack, а конце - восстанавливается 15 регистров общего назначения, хотя вызываемые из прерывания функции не требуют такого количества регистров. Я сначала подумал, что всё дело в том, что вызываемая из прерывания функция находится в другом модуле проекта, перенёс её в тот же модуль, где находится процедура прерывания, но отличий не увидел. Такое же ненужное сохранение множества регистров.
Разумное сохранение регистров я увидел только тогда, когда компилятор включил текст вызываемой функции в процедуру прерывания (inline). Если по какой-то причине inline функции не получается, снова бессмысленное сохранение регистров.
Чтобы не быть голословным, привожу код:
Код
#include <ioavr.h>

#pragma optimize=no_inline
void DoNothing()
{
}

#pragma vector = TIMER1_COMPA_vect
__interrupt void ext_int0_isr_routine(void)
{
  DoNothing();
}

int main( void )
{
  return 0;
}

Оптимизация стоит максимальная по скорости.
Подскажите, как этого можно избежать? Очень хотелось бы из прерывания вызывать функции, в т.ч. из других модулей, и иметь при этом оптимальный код.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Dmitro25
сообщение Mar 31 2010, 06:47
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



2mempfis:
Цитата
Попробуйте вместо вызова функции в прерывании устанавливать глобальный флаг. А в основном цикле анализировать - если флаг установлен то необходим вызов этой функции.

Подход понятный, и я его использую. Но в некоторых случаях хочется всё же немедленно выполнить какие-то действия.
Цитата
Если в прерывании идёт вызов функций то иар на всякий случай сохраняет все регистры

Вот это мне и непонятно. Зачем?
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 31 2010, 08:06
Сообщение #3


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Dmitro25 @ Mar 31 2010, 13:47) *
Вот это мне и непонятно. Зачем?

Как раз понятное и объяснимое поведение. По-другому просто и быть не может. У IAR есть соглашения о вызовах функций в части распределения регистров. Все регистры в этом контексте делятся на две группы: local и scratch. Регистры группы scratch могут использоваться внутри любой функции без сохранения, регистры из группы local, если компилятор "хочет" использовать этот регистр, он должен его значение сначала сохранить, перед выходом восстановить. Этим достигается целостность данных при вызове подпрограмм (функций).

При обычной работе программы комплятор перед вызовом функции не хранит в scratch регистрах ничего ценного - вызываемая функция их будет использовать без сохранения, компилятор об этом "знает" и все ценное хранит в local регистрах и в стеке. Теперь представьте, что вызвался обработчик прерываний (ISR). Как вы знаете, внутри ISR абсолютно все регистры, которые компилятор использует, он обязан сохранить/восстановить - это происходит в силу того, что ISR вызывается асинхронно по отношению к выполнению основной программы, что означает, что при входе в ISR компилятор ничего не знает о состоянии контекста прерванной программы (состоянии регистров в частности - может там все было прервано в момент сохранения значений local регистров и или данных из scratch регистров в стек). И компилятор, видя код, решает сколько ему надо регистров, их он и сохраняет/восстанавливает.

Теперь представьте, что внутри ISR вызывается функция. Если компилятор видит ее код (функция встраиваемая), то ситуация сводится к вышеописанной. А если функция невстраиваемая, то компилятор просто не знает, какие из scratch регистров могут внутри нее использоваться, поэтому он просто обязан сохранить их все во избежание нарушения целостности данных и неправильной работы программы.

Поэтому либо не вызывайте функции из ISR, либо делайте их гарантировано встраиваемыми. Для этого есть хорошая прагма #pragma inline=forced.

У AVR, насколько помню, к scratch регистрам относятся r16-r25, r30-r31 и r0-r4. Вот они и должны сохраняться всегда.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Dmitro25   Оптимизация прерываний   Mar 31 2010, 05:47
- - mempfis_   КодВозникло желание посмотреть, какой код формируе...   Mar 31 2010, 06:34
|- - MrYuran   Цитата(Dmitro25 @ Mar 31 2010, 09:47) Под...   Mar 31 2010, 07:24
- - Dmitro25   2dxp: ЦитатаКак раз понятное и объяснимое поведени...   Mar 31 2010, 08:28
|- - dxp   Цитата(Dmitro25 @ Mar 31 2010, 15:28) 2dx...   Mar 31 2010, 09:26
|- - Сергей Борщ   Цитата(Dmitro25 @ Mar 31 2010, 10:28) пер...   Mar 31 2010, 09:33
|- - defunct   Цитата(Dmitro25 @ Mar 31 2010, 11:28) Зад...   Apr 4 2010, 23:06
- - Dmitro25   2dxp: Спасибо за советы. Всё-таки не удержусь от т...   Mar 31 2010, 10:31
|- - Сергей Борщ   Цитата(Dmitro25 @ Mar 31 2010, 12:31) Есл...   Mar 31 2010, 10:51
|- - dxp   Цитата(Dmitro25 @ Mar 31 2010, 17:31) В п...   Mar 31 2010, 11:28
- - Dmitro25   2Сергей Борщ: ЦитатаТогда внесите обработчик в сиш...   Mar 31 2010, 11:48
|- - MrYuran   Цитата(Dmitro25 @ Mar 31 2010, 14:48) При...   Mar 31 2010, 12:59
- - MALLOY2   Вам же говорили глобальный флаг, а в основном цикл...   Mar 31 2010, 12:44
- - Dmitro25   2:MALLOY2 Глобальный флаг у меня в другом месте в ...   Mar 31 2010, 13:17
- - XVR   Что бы компилятор понял в процедуре прерывания, чт...   Apr 1 2010, 10:44


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 15:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.0139 секунд с 7
ELECTRONIX ©2004-2016