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

 
 
> Замена обработчика прерывания в 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
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 14)
733259
сообщение Dec 16 2008, 04:35
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 8-03-05
Пользователь №: 3 146



ИМХО никак, т.к. в AVR адреса векторов фиксированые, только в ISR вызывать функцию по условию.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Dec 16 2008, 05:59
Сообщение #3


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

Группа: Свой
Сообщений: 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
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 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
Сообщение #5


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

Группа: Свой
Сообщений: 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
Qwertty
сообщение Dec 16 2008, 08:36
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Вызов функции по указателю внутри обработчика ведет к сохранению ВСЕХ регистров в стеке. И восстановлению их при выходе. Не быстрый обработчик получается sad.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 16 2008, 09:19
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Векторизация прерываний. Например, int1
Soft_vectors.S
Код
#include <avr/io.h>
.extern vector_int1
.global INT1_vect
INT1_vect:
  push r30
  in  r30,SREG
  push r30
  push r31
  lds   r30,vector_int1
  lds   r31,(vector_int1+1)
  icall
  pop  r31
  pop  r30
  out  SREG,r30
  pop  r30
  reti

Просто добавьте в проект...
Go to the top of the page
 
+Quote Post
PhX
сообщение Dec 16 2008, 09:19
Сообщение #8


Местный
***

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



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

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

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


--------------------
Если все, то не я...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 16 2008, 09:38
Сообщение #9


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(_Pasha @ Dec 16 2008, 13:19) *
Просто добавьте в проект...

Ммм... забыл добавить сохранение/восстановление SREG. Исправлено.
Go to the top of the page
 
+Quote Post
aesok
сообщение Dec 16 2008, 10:23
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(_Pasha @ Dec 16 2008, 12:19) *
Векторизация прерываний. Например, int1
Soft_vectors.S
Код
#include <avr/io.h>
.extern vector_int1
.global INT1_vect
INT1_vect:
  push r30
  in  r30,SREG
  push r30
  push r31
  lds   r30,vector_int1
  lds   r31,(vector_int1+1)
  icall
  pop  r31
  pop  r30
  out  SREG,r30
  pop  r30
  reti

Просто добавьте в проект...


Что вам такого плохого сделали люди, что бы советовать им такую гадость???? Компилятор не просто так сохраняет r0, r1 и call-used регстры. Если их не сохранять то программа не будет работать.


Анатолий.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 16 2008, 10:48
Сообщение #11


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(aesok @ Dec 16 2008, 14:23) *
Компилятор не просто так сохраняет r0, r1 и call-used регстры.

Про r0 r1 - такида, надо добавить, а вот call-used все-же должны отсутствовать по причине того, что обработчики прерываний у нас без параметров. Правильно?
Go to the top of the page
 
+Quote Post
733259
сообщение Dec 16 2008, 11:24
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 8-03-05
Пользователь №: 3 146



А в своем теле функция никакие регистры не использует?
Даже r24?
ИМХО можно так делать, если вызываемые функции написать на ассемблере (проанализировать листинг) и самостоятельно сохранять регистры.
Кстати Ваш ужас реализуется куда короче и с правильным сохранением:
Код
SYGNAL(SIG_INTERRUPT1){
  asm("icall"::"z"(vector_int1);
}
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 16 2008, 11:38
Сообщение #13


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(733259 @ Dec 16 2008, 15:24) *
А в своем теле функция никакие регистры не использует?

Понятно. Забыл о том, что из асма сишные функции никогда в жизни не вызывал и что за сохранение call-used отвечает вызывающий. Тогда это действительно проблема.
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 16 2008, 17:04
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



в некоторых случаях можно делать перезапись векторов прямо во flash... правда, при условии, что это будет достаточно редко... очень редко smile.gif
а если достаточно всего пары вариантов обработчиков - то можно манипулировать IVSEL, переключая таблицы...

все эти варианты - не для любого AVR, разумеется...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 16 2008, 18:10
Сообщение #15


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(aesok @ Dec 16 2008, 14:23) *
Компилятор не просто так сохраняет r0, r1 и call-used регстры.

Последний релиз сохраняет минимум пару лишних регистров. Если интересно, завтра выложу код.
Go to the top of the page
 
+Quote Post

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

 


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


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