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

 
 
> Замена обработчика прерывания в WinAVR
PhX
сообщение Dec 16 2008, 04:23
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249



Нужно использовать различные обработчики прерывания в зависимости от случая. Например в начале программы
обработчик_пр = функция 1
Код
ISR(INT1_vect)
{
обработчик_пр
}

а затем где-то по далее необходимо заменить его на
обработчик_пр = функция 2
Как это грамотно сделать в WinAVR?


--------------------
Если все, то не я...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
MrYuran
сообщение Dec 16 2008, 05:59
Сообщение #2


Беспросветный оптимист
******

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



Определить указатель на функцию и поставить его в тело обработчика прерывания. Указателю между делом можно присваивать адреса разных функций. Издержки - команда CALL в теле обработчика прерываний. Зато задержка будет фиксированной и независимой от условий, как в случае switch или if/else.

Код
typedef void ( *pxTBFunctionHandler ) ( void );  // объявление типа указателя на функцию

pxTBFunctionHandler pxMBPortCBTimerExpired; // объявление указателя на функцию

pxMBPortCBTimerExpired = (void*)xMBRTUTimerT35Expired; // инициализация указателя



interrupt (TIMERA0_VECTOR) prvvMBTimerIRQHandler( void )
{    
    ( void )pxMBPortCBTimerExpired(  );
}

Пример безжалостно выдран из FreeModbus.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
PhX
сообщение Dec 16 2008, 06:13
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249



Цитата(MrYuran @ Dec 16 2008, 09:59) *
Определить указатель на функцию и поставить его в тело обработчика прерывания. Указателю между делом можно присваивать адреса разных функций. Издержки - команда CALL в теле обработчика прерываний. Зато задержка будет фиксированной и независимой от условий, как в случае switch или if/else.

+1 smile.gif
Кстати это очень удобно.
Код
//Прототипы функций
void isr1(void);
void isr2(void);
//Указатель на функцию обработчик
void (* cur_isr)(void) = isr1;


void isr1(void)
{
// тело обработчика 1
}

void isr2(void)
{
// тело обработчика 2
}

ISR(INT1_vect)
{
(* cur_isr)();
}

int main(void)
{
// ля-ля тополя...
...
cur_isr = isr2;
...
}


--------------------
Если все, то не я...
Go to the top of the page
 
+Quote Post
ReAl
сообщение Dec 16 2008, 07:49
Сообщение #4


Нечётный пользователь.
******

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



Цитата(PhX @ Dec 16 2008, 08:13) *
Код
int main(void)
{
// ля-ля тополя...
...
cur_isr = isr2;
...
}
Оно, конечно, "само собой разумеется", но cur_isr = isr2; надо в атомарный блок взять.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
PhX
сообщение Dec 16 2008, 09:19
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249



Цитата(ReAl @ Dec 16 2008, 11:49) *
Оно, конечно, "само собой разумеется", но cur_isr = isr2; надо в атомарный блок взять.

А как это сделать?
Цитата
Вызов функции по указателю внутри обработчика ведет к сохранению ВСЕХ регистров в стеке. И восстановлению их при выходе. Не быстрый обработчик получается

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


--------------------
Если все, то не я...
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 20 2008, 01:03
Сообщение #6


кекс
******

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



Цитата(PhX @ Dec 16 2008, 11:19) *
Ну хоть как-то. Не очень хорошо конечно, но что делать. Может есть способ лучше?
Правда, в моем случае, быстродействия достаточно.

На мой взгляд, это отличный способ. Почему я так думаю - потому что:
1. Сохранение и восстановление всех регистров это всего лишь 128 тактов вход-выход в обработчик.
2. Как правило, необходимость в подмене обработчика прерывания происходит тогда, когда кардинально что-то меняется в работе программы, например - замена протокола обмена. В таких случаях логично предположить, что подменяемые обработчики "тяжеловесны" и по времени выполнения занимают гораздо больше 128 тактов.
3. Не надо гнаться за скоростью там где ее хватает, тем более в ущерб переносимости и читаемости кода.

Из чего делаем вывод - всего за 128 тактов получаем простой, прозрачный (легко читаемый), относительно безопасный, и прекрасно портируемый код на любую платформу.
Хорошо это, не очень хорошо, или совсем плохо - судить Вам ;>



Правда есть еще один тупой и топорный способ, о котором почему-то забыли упомянуть, хотя он обладает еще таким свойством как "абсолютная" безопасность smile.gif :
Код
ISR()
{
    prefix stuff

    if (...)
      handler1();
    else if (..)
      handler2();
    else
      common_handler();

   postfix stuff
}

при "сказочной" тупизне и кажущейся неоптимальности, вот какими плюсами сие обладает:
- Никакого гемороя с ассемблером.
- Тривиальная простота.
- Абсолютная безопастность - есть уверенность, что из обработчика выйдем всегда, и всегда выйдем правильно, нет риска неверного указателя в RAM.
- Возможность не только "подменять" обработчик, но и "параллельно" выполнять несколько обработчиков (например, по одному интерфейсу обслуживать несколько протоколов обмена).
- Легко портируемый.
- Нативно оптимизируемый - если все функции handler1, 2, и т.п. объявить в одном файле с обработчиком как static, то результирующий код получится эффективным - т.к. оптимизатор сделает свое дело сам.



Все шаманства с ассемблером и оптимизации "ради оптимизации" - это Зло. Лучше делать упор на функциональность, портируемость, читаемость. А вот когда действительно не будет хватать производительности и нет возможности поставить более шустрый кварц / камень, тогда (и только тогда) можно прибегнуть к извращениям на асм'е.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- PhX   Замена обработчика прерывания в WinAVR   Dec 16 2008, 04:23
- - 733259   ИМХО никак, т.к. в AVR адреса векторов фиксированы...   Dec 16 2008, 04:35
- - Qwertty   Вызов функции по указателю внутри обработчика веде...   Dec 16 2008, 08:36
|- - MrYuran   Цитата(Qwertty @ Dec 16 2008, 11:36) Вызо...   Dec 17 2008, 11:34
|- - _Pasha   Цитата(MrYuran @ Dec 17 2008, 15:34) а чт...   Dec 17 2008, 11:46
|- - Сергей Борщ   Цитата(_Pasha @ Dec 17 2008, 13:46) Не, т...   Dec 17 2008, 14:31
- - _Pasha   Векторизация прерываний. Например, int1 Soft_vect...   Dec 16 2008, 09:19
|- - _Pasha   Цитата(_Pasha @ Dec 16 2008, 13:19) Прост...   Dec 16 2008, 09:38
|- - aesok   Цитата(_Pasha @ Dec 16 2008, 12:19) Векто...   Dec 16 2008, 10:23
|- - _Pasha   Цитата(aesok @ Dec 16 2008, 14:23) Компил...   Dec 16 2008, 10:48
|- - _Pasha   Цитата(aesok @ Dec 16 2008, 14:23) Компил...   Dec 16 2008, 18:10
- - 733259   А в своем теле функция никакие регистры не использ...   Dec 16 2008, 11:24
|- - _Pasha   Цитата(733259 @ Dec 16 2008, 15:24) А в с...   Dec 16 2008, 11:38
- - ARV   в некоторых случаях можно делать перезапись вектор...   Dec 16 2008, 17:04
- - singlskv   Господа, Вы занимаетесь просто какой-то х.р..й ......   Dec 16 2008, 18:44
|- - _Pasha   Цитата(singlskv @ Dec 16 2008, 22:44) Гос...   Dec 16 2008, 19:50
|- - singlskv   Цитата(_Pasha @ Dec 16 2008, 22:50) Т.е. ...   Dec 16 2008, 20:03
- - 733259   ЦитатаСправедливости ради, такой подход имеет один...   Dec 17 2008, 02:01
|- - _Pasha   Цитата(733259 @ Dec 17 2008, 06:01) прави...   Dec 17 2008, 10:17
|- - singlskv   Цитата(_Pasha @ Dec 17 2008, 13:17) Следо...   Dec 17 2008, 11:09
|- - ReAl   Цитата(_Pasha @ Dec 17 2008, 12:17) Есть ...   Dec 20 2008, 16:00
|- - _Pasha   Цитата(ReAl @ Dec 20 2008, 20:00) посмотр...   Dec 20 2008, 16:26
- - Rst7   Не знаю, можно ли все, что я тут напишу, реализова...   Dec 17 2008, 07:42
- - 733259   Что Ваш вариант в 20 тактов, что через icall в 21....   Dec 17 2008, 07:55
- - Rst7   ЦитатаЧто Ваш вариант в 20 тактов, что через icall...   Dec 17 2008, 08:19
- - ReAl   Я погонял компиляцию этого дела в разных режимах. ...   Dec 20 2008, 16:34
- - _Pasha   Цитата(ReAl @ Dec 20 2008, 20:34) что даё...   Dec 20 2008, 16:49


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

 


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


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