|
Замена обработчика прерывания в WinAVR |
|
|
|
Dec 16 2008, 04:23
|

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

|
Нужно использовать различные обработчики прерывания в зависимости от случая. Например в начале программы обработчик_пр = функция 1 Код ISR(INT1_vect) { обработчик_пр } а затем где-то по далее необходимо заменить его на обработчик_пр = функция 2 Как это грамотно сделать в WinAVR?
--------------------
Если все, то не я...
|
|
|
|
|
 |
Ответов
|
Dec 17 2008, 02:01
|
Местный
  
Группа: Участник
Сообщений: 205
Регистрация: 8-03-05
Пользователь №: 3 146

|
Цитата Справедливости ради, такой подход имеет один побочный эфект, прерывания будут разрешены еще до окончательного выхода из нашего главного обработчика С __attribute__((interrupt)) прерывания будут разрешены сразу после входа в INT0_vect (INT0_vect), первой командой будет sei. C __attribute__((signal)) такого не будет, ИМХО правильнее __attribute__((signal,used)). К тому же вариант singlskv не универсален - переключаются векторы INT0, INT1, а если они нужны? В случае "просто" функций - компилятор выдаст предупреждение "misspelled interrupt handler" - из-за этого данный вариант мне показался не подходящим. ИМХО в реале накладные расходы на if будут меньше push r30, icall и т.д. Цитата Как приятно иногда сказать: знатоки, блин. Не совсем понял иронию.
|
|
|
|
|
Dec 17 2008, 10:17
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(733259 @ Dec 17 2008, 06:01)  правильнее __attribute__((signal,used)). К тому же вариант singlskv не универсален - переключаются векторы INT0, INT1, а если они нужны? Следовательно, как компромисс, можно просто заюзать все неиспользуемые вектора. Есть у меня еще в стадии тестирования субвекторизация. Допустим, у нас есть функция, при должном внимании к построению которой можно добиться, что она состоит из набора независимых блоков, между которыми компилятор не будет осуществлять операции по сохранению используемых регистров Код void foo(void) { { block 1 } //........ { block N } } Сделаем необходимый инструментарий Код typedef uint16_t pc_type; // пока обошел указатели стороной
uint8_t wherePC(void* pcreg) __attribute__((naked)); void setPC(pc_type newPC) __attribute__((naked)); /*Обертка для субвекторов*/ #define SubVector(t_name) if(wherePC(&t_name)) WherePC заточено таким образом, чтобы возвращать 0 при вызове, а в параметре - адрес, с которого ее вызывали, исключая обработку возвращаемого значения. Код void setPC(pc_type newPC) { asm volatile("ijmp" : : "z" (newPC)); }
uint8_t wherePC(void* pcreg) { asm volatile ( "pop r25" "\n\t" "pop r24" "\n\t" "adiw r24,2" "\n\t" "st Z, r24" "\n\t" "std Z+1,r25" "\n\t" "movw r30,r24" "\n\t" "sbiw r30,2" "\n\t" "clr r24" "\n\t" "ijmp" "\n\t" ::"z" (pcreg)); } Используя SubVector(имя_переменной_указателя_на_блок) Код void foo(void) { static pc_type sv[3]; static uint8_t work = 0; if(work) {// код, использующий косв. переход на sv[n] set_PC(sv[1]); } else { SubVector(sv[0]) { block 1 } SubVector(sv[1]) { block 2 } SubVector(sv[2]) { block 3 } work = 1; } return; } В итоге при первом вызове получаем адреса блоков кода в переменных sv[], но сами блоки не выполняем, по аналогии с setjmp, а при последующих вызовах - переходим в кратчайшие сроки к независимому блоку. В данном контексте это должно обеспечить выигрыш по сравнению со switch() Просьба потестить эти примитивы и высказать мнения о применимости. Заранее спасибо.
|
|
|
|
|
Dec 20 2008, 16:00
|

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

|
Цитата(_Pasha @ Dec 17 2008, 12:17)  Есть у меня еще в стадии тестирования субвекторизация. Есть несколько менее переносимый, зато более эффективный способ. В том смысле, что переписать эту субвекторизацию на другой асм другого процессора+компилятора можно, как можно и посмотреть реализацию структуры jump_buf и сделать переключатель, как у Rst7, привязанный к процессору+компилятору, но переписываемый под любую другую компбинацию. А тут - привязка к конкретному инструменту. Но раз в примере всё равно использован gcc, то... в нём можно взять адрес метки. Во-первых, при этом можно WherePC сделать макросом, адрес вычисляется линкером: Код #define glue2(a,b) a##b #define WPC_LABEL(a,b) glue2(a,b)
#define WherePC(a) { a = &&WPC_LABEL(WPC,__LINE__); WPC_LABEL(WPC,__LINE__):; }
volatile unsigned char a;
void *p1; void *p2;
void foo() { ++a; WherePC(p1); ++a; WherePC(p2); ++a; } И результат компиляции: Код foo: lds r24,a subi r24,lo8(-(1)) sts a,r24 ldi r24,lo8(gs(.L2)) ldi r25,hi8(gs(.L2)) sts (p1)+1,r25 sts p1,r24 .L2: lds r24,a subi r24,lo8(-(1)) sts a,r24 ldi r24,lo8(gs(.L3)) ldi r25,hi8(gs(.L3)) sts (p2)+1,r25 sts p2,r24 .L3: lds r24,a subi r24,lo8(-(1)) sts a,r24 ret Во вторых, этот макрос при такой постановке вопроса не нужен вообще: http://forum.sources.ru/index.php?showtopi...p;#entry1929594В переводе на AVR-ский язык Код ISR(INT0_vect) { static void *next_state = &&start;
goto *next_state;
start: next_state = &&idle; return;
idle: if (PINB & 0x01) { PORTB |= 0x80; next_state = &&drain; } return;
drain: if (PINB & 0x02) { PORTB &= ~0x80; next_state = &&idle; } return; } И результат: Код .text .size foo, .-foo .global __vector_1 __vector_1: push __zero_reg__ push __tmp_reg__ in __tmp_reg__,__SREG__ push __tmp_reg__ clr __zero_reg__ push r24 push r25 push r30 push r31
lds r30,next_state.1519 lds r31,(next_state.1519)+1 ijmp .L6: .L13: ldi r24,lo8(gs(.L7)) ldi r25,hi8(gs(.L7)) sts (next_state.1519)+1,r25 sts next_state.1519,r24 rjmp .L12 .L7: sbis 35-0x20,0 rjmp .L12 sbi 37-0x20,7 ldi r24,lo8(gs(.L10)) ldi r25,hi8(gs(.L10)) sts (next_state.1519)+1,r25 sts next_state.1519,r24 rjmp .L12 .L10: sbis 35-0x20,1 rjmp .L12 cbi 37-0x20,7 rjmp .L13 .L12:
pop r31 pop r30 pop r25 pop r24 pop __tmp_reg__ out __SREG__,__tmp_reg__ pop __tmp_reg__ pop __zero_reg__ reti
.data next_state.1519: .word gs(.L6)
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
Сообщений в этой теме
PhX Замена обработчика прерывания в WinAVR Dec 16 2008, 04:23 733259 ИМХО никак, т.к. в AVR адреса векторов фиксированы... Dec 16 2008, 04:35 MrYuran Определить указатель на функцию и поставить его в ... Dec 16 2008, 05:59 PhX Цитата(MrYuran @ Dec 16 2008, 09:59) Опре... Dec 16 2008, 06:13  ReAl Цитата(PhX @ Dec 16 2008, 08:13) Кодint m... Dec 16 2008, 07:49   PhX Цитата(ReAl @ Dec 16 2008, 11:49) Оно, ко... Dec 16 2008, 09:19    defunct Цитата(PhX @ Dec 16 2008, 11:19) Ну хоть ... Dec 20 2008, 01:03 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  singlskv Цитата(_Pasha @ Dec 17 2008, 13:17) Следо... Dec 17 2008, 11:09   _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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|