|
|
  |
WinAVR и RETI |
|
|
|
Mar 3 2007, 11:09
|

Местный
  
Группа: Свой
Сообщений: 360
Регистрация: 3-01-06
Из: Украина Запорожская обл.
Пользователь №: 12 792

|
Цитата(Kuzmi4 @ Mar 3 2007, 11:25)  В общем вопрос этот возник давно, но как то раньше я без этого обходился, а тут уж совсем невтерпёж стало. Собсно вопрос такой - в иаре можно в таблице прерываний расположить для неиспользуемых векторов инструкцию RETI. На асме - вообще молчу. Но как это сделать для WinAVR??(исползую WinAVR-20060421). Раньше,когда надо было, извращался по разному, вплоть до СПМ... Но в принципе должно ж это как то решаться на уровне компилятора, как в иаре??? Может это поможет Код ISR (TIMER1_OVF_vect) // ето для переполнения таймера 1 {
} и так для каждого прерывания компилятор сделает всё как нада...
|
|
|
|
|
Mar 3 2007, 11:46
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
вот так делается пустое прерывание EMPTY_INTERRUPT(vector); или что то же самое void vector (void) __attribute__ ((naked)); void vector (void) { __asm__ __volatile__ ("reti" :  ; } где на место vector подставляем свой interrupt например TIMER1_OVF_vect можно так же перенаправить все неиспользованные прерывания на один обработчик ISR(__vector_default); или что то же самое void vector (void) __attribute__ ((signal)); void vector (void) {} соответственно можно написать вот так: EMPTY_INTERRUPT(__vector_default); правда тогда reti подставится не в саму таблицу а в отдельную функцию чтобы подставить прямо в таблицу нужно прописать EMPTY_INTERRUPT для каждого неиспользуемого только нужно не забыть #include <avr/interrupt.h>
|
|
|
|
|
Mar 3 2007, 13:30
|

Гуру
     
Группа: Свой
Сообщений: 3 304
Регистрация: 13-02-07
Из: 55°55′5″ 37°52′16″
Пользователь №: 25 329

|
Хм.. вот что получилось.. ---------------------- #include<avr/io.h> #include <avr/iom168.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #include <util/twi.h> #include <util/crc16.h>
// Medium speed - ATMega168 // /////////////////////////////// #define F_CPU 7372800 //Hz /////////////////////////////// #include <util/delay.h> /////////////////////////////// #include "file.h" ///////////////////////////////
EMPTY_INTERRUPT(INT0_vect);
int main (void) {
return 1; } ----------------------- а на асме --------- +00000000: 940C0034 JMP 0x00000034 Jump +00000002: 940C0051 JMP 0x00000051 Jump +00000004: 940C004F JMP 0x0000004F Jump +00000006: 940C004F JMP 0x0000004F Jump +00000008: 940C004F JMP 0x0000004F Jump +0000000A: 940C004F JMP 0x0000004F Jump +0000000C: 940C004F JMP 0x0000004F Jump +0000000E: 940C004F JMP 0x0000004F Jump +00000010: 940C004F JMP 0x0000004F Jump +00000012: 940C004F JMP 0x0000004F Jump +00000014: 940C004F JMP 0x0000004F Jump +00000016: 940C004F JMP 0x0000004F Jump +00000018: 940C004F JMP 0x0000004F Jump +0000001A: 940C004F JMP 0x0000004F Jump +0000001C: 940C004F JMP 0x0000004F Jump +0000001E: 940C004F JMP 0x0000004F Jump +00000020: 940C004F JMP 0x0000004F Jump +00000022: 940C004F JMP 0x0000004F Jump +00000024: 940C004F JMP 0x0000004F Jump +00000026: 940C004F JMP 0x0000004F Jump +00000028: 940C004F JMP 0x0000004F Jump +0000002A: 940C004F JMP 0x0000004F Jump +0000002C: 940C004F JMP 0x0000004F Jump +0000002E: 940C004F JMP 0x0000004F Jump +00000030: 940C004F JMP 0x0000004F Jump +00000032: 940C004F JMP 0x0000004F Jump +00000034: 2411 CLR R1 Clear Register +00000035: BE1F OUT 0x3F,R1 Out to I/O location +00000036: EFCF SER R28 Set Register +00000037: E0D4 LDI R29,0x04 Load immediate +00000038: BFDE OUT 0x3E,R29 Out to I/O location +00000039: BFCD OUT 0x3D,R28 Out to I/O location +0000003A: E011 LDI R17,0x01 Load immediate +0000003B: E0A0 LDI R26,0x00 Load immediate +0000003C: E0B1 LDI R27,0x01 Load immediate +0000003D: EBE6 LDI R30,0xB6 Load immediate +0000003E: E0F0 LDI R31,0x00 Load immediate +0000003F: C002 RJMP PC+0x0003 Relative jump +00000040: 9005 LPM R0,Z+ Load program memory and postincrement +00000041: 920D ST X+,R0 Store indirect and postincrement +00000042: 30A0 CPI R26,0x00 Compare with immediate +00000043: 07B1 CPC R27,R17 Compare with carry +00000044: F7D9 BRNE PC-0x04 Branch if not equal +00000045: E011 LDI R17,0x01 Load immediate +00000046: E0A0 LDI R26,0x00 Load immediate +00000047: E0B1 LDI R27,0x01 Load immediate +00000048: C001 RJMP PC+0x0002 Relative jump +00000049: 921D ST X+,R1 Store indirect and postincrement +0000004A: 30A0 CPI R26,0x00 Compare with immediate +0000004B: 07B1 CPC R27,R17 Compare with carry +0000004C: F7E1 BRNE PC-0x03 Branch if not equal +0000004D: 940C0052 JMP 0x00000052 Jump +0000004F: 940C0000 JMP 0x00000000 Jump @00000051: __vector_1 ---- tst_reti.c ----------------------------------------------------------------------------------- 17: EMPTY_INTERRUPT(INT0_vect); +00000051: 9518 RETI Interrupt return @00000052: main 22: { +00000052: EFCF SER R28 Set Register +00000053: E0D4 LDI R29,0x04 Load immediate +00000054: BFDE OUT 0x3E,R29 Out to I/O location +00000055: BFCD OUT 0x3D,R28 Out to I/O location 25: } +00000056: E081 LDI R24,0x01 Load immediate +00000057: E090 LDI R25,0x00 Load immediate +00000058: 940C005A JMP 0x0000005A Jump +0000005A: CFFF RJMP PC-0x0000 Relative jump
--------------------------
а я немного не то имелл вииду - мне бы в таблицу засунуть этот RETI ....
Втсавка вместо EMPTY_INTERRUPT - void INT0_vect (void) даёт тож самое...
Сообщение отредактировал Kuzmi4 - Mar 3 2007, 13:34
|
|
|
|
|
Mar 3 2007, 14:00
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Kuzmi4 @ Mar 3 2007, 10:25)  В общем вопрос этот возник давно, но как то раньше я без этого обходился, а тут уж совсем невтерпёж стало. Собсно вопрос такой - в иаре можно в таблице прерываний расположить для неиспользуемых векторов инструкцию RETI. На асме - вообще молчу. Но как это сделать для WinAVR??(исползую WinAVR-20060421). Раньше,когда надо было, извращался по разному, вплоть до СПМ... Но в принципе должно ж это как то решаться на уровне компилятора, как в иаре??? Теоритечески это можно сделать если переписать 'gcrt1.S', где в таблице прерываний для всех неиспользуемых прерываний вставить инструкцию 'RETI', и включить его в свой проект. Только я не понял, какой в этом практический смысл? Анатолий.
|
|
|
|
|
Mar 3 2007, 14:20
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Kuzmi4 @ Mar 3 2007, 14:06)  Ну как сказать - практический смысл в принципе есть. Вот и я про тоже, никакого практического смысла нет, есть только 'в приеципе'. Цитата Если написать правильно программу - то никакого, с одной стороны, а с другой - если человек вдруг лепил на скорую руку проэкт и забыл чтото(взрослые дяди конечно так не делают , но мне далеко до них) - то этот ретИ в принципе очень поможет. Разрешить только те прерывании для которых есть обработчики, это максимум 2 минуты работы при любом уровне подготовки. Цитата ну + ещё то , что не занимается пару десятков байт на перенаправление... При использовании "EMPTY_INTERRUPT(xxx_vect);" - все накладные расходы это одна лишняя инсрукция. Анатолий.
Сообщение отредактировал aesok - Mar 3 2007, 14:21
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|