|
__raw прерывания |
|
|
|
 |
Ответов
(15 - 29)
|
Jun 12 2007, 16:14
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Цитата(singlskv @ Jun 12 2007, 20:05)  Если честно, я вобще не вникал в суть алгоритма/проблемы автора  На сахаре автар попросил не вникать А вобще как-то это все странно, 25 лишних тактов и уже мерцание... Афтар, приведите минимальный код в котором будет эта проблема http://caxapa.ru/90428.html + прерывание от адц с размешением в память 32 байт и выставлением флага.
|
|
|
|
|
Jun 12 2007, 16:15
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Т.Достоевский @ Jun 12 2007, 19:56)  Вот это пожалуйста поподробней!!! Так и пытался сделать но не пойму с синтаксисом (в С новичок). Не принимает он у меня jmp через функцию. jmp на АСМе на абсолютный адрес где лежит jmp "фиктивного" обработчика(нужной С функции). На С скорее всего такой трюк (jmp) описать не получится, тк нужно сохранять/восстанавливать используемые для этого регистры
|
|
|
|
|
Jun 12 2007, 16:19
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Цитата(singlskv @ Jun 12 2007, 20:15)  jmp на АСМе на абсолютный адрес где лежит jmp "фиктивного" обработчика(нужной С функции). На С скорее всего такой трюк (jmp) описать не получится, тк нужно сохранять/восстанавливать используемые для этого регистры Получится, если фиктивное сделать без __raw. Не получается абсолютный адрес, нету такой, есть только относительный RJMP. Если сделать так то и асма не нужно тк С код будет соизмерим. Но не вызывает он функции обозначенные как __interrupt!
Сообщение отредактировал Т.Достоевский - Jun 12 2007, 16:24
|
|
|
|
|
Jun 12 2007, 16:36
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
по Вашей ссылке прерывания ADC не увидел, дальше не копал Цитата(Т.Достоевский @ Jun 12 2007, 20:19)  Получится, если фиктивное сделать без __raw. Дык __raw подразумевает сохранение ручками Цитата Если сделать так то и асма не нужно тк С код будет соизмерим. Но не вызывает он функции обозначенные как __interrupt! конечно не вызывает, interrupt это не функция там прокатит только абсолютный jmp можете его в ASM обработчике через DB xx, xx написать
|
|
|
|
|
Jun 12 2007, 17:15
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Цитата(slog @ Jun 12 2007, 21:11)  Ты и тут уже :-) __indirect_jump_to((unsigned long)&Имя_функции);
Стек может испортиться, надо смотреть что компилятор наделает, и если что исправлять. Вот это уже интерестней. А Я везде, просто не знал что иар это игрушка
|
|
|
|
|
Jun 12 2007, 17:21
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Т.Достоевский @ Jun 12 2007, 21:15)  Вот это уже интерестней.
А Я везде, просто не знал что иар это игрушка не..., inderect jump для прерываний не прокатит скорее смотри на: _OPC(opCode) ну или что то же самое на __insert_opcode(opCode)
|
|
|
|
|
Jun 12 2007, 19:57
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(singlskv @ Jun 12 2007, 23:21)  не..., inderect jump для прерываний не прокатит скорее смотри на: _OPC(opCode) ну или что то же самое на __insert_opcode(opCode) В ИАР же вроде стандартная Сишная директива asm работает Т.Достоевский, попробуйте так Код #pragma vector=TIMER_VECTOR __interrupt __raw void Timer_ISR(void) { PORTx=1; asm("PUSH R31"); asm("PUSH R30"); asm("PUSH R29"); .... funcBlaBlaBla(); ... asm("POP R29"); asm("POP R30"); asm("POP R31"); }
|
|
|
|
|
Jun 12 2007, 20:14
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Цитата(slog @ Jun 12 2007, 21:11)  __indirect_jump_to((unsigned long)&Имя_функции); Уиточни пожалуйста мнемонику. Особенно если вместо имя функции прямой адрес. А то я уже час буквы гоняю. Цитата(rezident @ Jun 12 2007, 23:57)  В ИАР же вроде стандартная Сишная директива asm работает Т.Достоевский, попробуйте так Код #pragma vector=TIMER_VECTOR __interrupt __raw void Timer_ISR(void) { PORTx=1; asm("PUSH R31"); asm("PUSH R30"); asm("PUSH R29"); .... funcBlaBlaBla(); ... asm("POP R29"); asm("POP R30"); asm("POP R31"); } все сохранять не нужно, а не все, тогда обработчик нельзя больше трогать, но скорее всего ПРИДЁТСЯ. В этом то и соль что придётся трогать не мне. Так бы я его на асме уже-б давно....
Сообщение отредактировал Т.Достоевский - Jun 12 2007, 20:16
|
|
|
|
|
Jun 13 2007, 08:12
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Делаю так обычно, ужос конечно, но что поделать: в .c Код #pragma vector=0x0E //Неиспользуемый вектор __interrupt void doADC(void) { char c=OCR1B; // unsigned int d; // __enable_interrupt(); switch(ADCstate) { default: .... и далее в .asm (тоже подключен к проекту) Код RSEG CODE:CODE:NOROOT(1) intADC: SEI EXTERN doADC RJMP doADC
COMMON INTVEC:CODE:ROOT(1) ORG 22 RJMP intADC END соответственно в асм можно вставить быстрый код И даже еще проще и лучше, без доп. асмов Код #include "iom8.h" #include "inavr.h"
//Также в настройках проекта запретить линкеру диагностику w22 #pragma diag_suppress=Ta006 __interrupt void IntLong(void) { __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); } #pragma diag_default=Ta006
#pragma vector=TIMER1_OVF_vect __raw __interrupt void I1(void) { __enable_interrupt(); ((void (*)(void))IntLong)(); }
int main( void ) { return 0; } Код 1 #include "iom8.h" 2 #include "inavr.h" 3 4 5 //Также линкеру запретить w22 6 #pragma diag_suppress=Ta006
\ In segment CODE, align 2, keep-with-next 7 __interrupt void IntLong(void) \ IntLong: 8 { 9 __no_operation(); \ 00000000 0000 NOP 10 __no_operation(); \ 00000002 0000 NOP 11 __no_operation(); \ 00000004 0000 NOP 12 __no_operation(); \ 00000006 0000 NOP 13 __no_operation(); \ 00000008 0000 NOP 14 __no_operation(); \ 0000000A 0000 NOP 15 } \ 0000000C 9518 RETI 16 #pragma diag_default=Ta006 17 18 #pragma vector=TIMER1_OVF_vect
\ In segment CODE, align 2, keep-with-next 19 __raw __interrupt void I1(void) \ I1: 20 { 21 __enable_interrupt(); \ 00000000 9478 SEI 22 ((void (*)(void))IntLong)(); \ 00000002 .... RCALL IntLong 23 } \ 00000004 9518 RETI 24
\ In segment CODE, align 2, keep-with-next 25 int main( void ) \ main: 26 { 27 return 0; \ 00000000 E000 LDI R16, 0 \ 00000002 E010 LDI R17, 0 \ 00000004 9508 RET 28 }
\ In segment INTVEC, offset 0x10, root \ `??I1??INTVEC 16`: \ 00000010 .... RJMP I1 Но все это костыли, применение которых должно быть оправдано на 150% и им не место в обычных проектах. И вот расширенный вариант, из которого все виднее Код #include "iom8.h" #include "inavr.h" #include "string.h"
//Также линкеру запретить w22 #pragma diag_suppress=Ta006 __interrupt void IntLong(void) { strcmp("abc","def"); } #pragma diag_default=Ta006
#pragma vector=TIMER1_OVF_vect __raw __interrupt void I1(void) { __enable_interrupt(); PORTB|=0x1; ((void (*)(void))IntLong)(); }
int main( void ) { return 0; } Код 1 #include "iom8.h"
\ In segment ABSOLUTE, at 0x38 \ union <unnamed> volatile __io _A_PORTB \ _A_PORTB: \ 00000000 DS 1 2 #include "inavr.h" 3 #include "string.h" 4 5 6 //Также линкеру запретить w22 7 #pragma diag_suppress=Ta006
\ In segment CODE, align 2, keep-with-next 8 __interrupt void IntLong(void) \ IntLong: 9 { \ 00000000 938A ST -Y, R24 \ 00000002 93FA ST -Y, R31 \ 00000004 93EA ST -Y, R30 \ 00000006 923A ST -Y, R3 \ 00000008 922A ST -Y, R2 \ 0000000A 921A ST -Y, R1 \ 0000000C 920A ST -Y, R0 \ 0000000E 937A ST -Y, R23 \ 00000010 936A ST -Y, R22 \ 00000012 935A ST -Y, R21 \ 00000014 934A ST -Y, R20 \ 00000016 933A ST -Y, R19 \ 00000018 932A ST -Y, R18 \ 0000001A 931A ST -Y, R17 \ 0000001C 930A ST -Y, R16 \ 0000001E B78F IN R24, 0x3F 10 strcmp("abc","def"); \ 00000020 .... LDI R18, LOW((`?<Constant "abc">` + 4)) \ 00000022 .... LDI R19, HIGH((`?<Constant "abc">` + 4)) \ 00000024 .... LDI R16, LOW(`?<Constant "abc">`) \ 00000026 .... LDI R17, (`?<Constant "abc">`) >> 8 \ 00000028 .... RCALL strcmp 11 } \ 0000002A BF8F OUT 0x3F, R24 \ 0000002C 9109 LD R16, Y+ \ 0000002E 9119 LD R17, Y+ \ 00000030 9129 LD R18, Y+ \ 00000032 9139 LD R19, Y+ \ 00000034 9149 LD R20, Y+ \ 00000036 9159 LD R21, Y+ \ 00000038 9169 LD R22, Y+ \ 0000003A 9179 LD R23, Y+ \ 0000003C 9009 LD R0, Y+ \ 0000003E 9019 LD R1, Y+ \ 00000040 9029 LD R2, Y+ \ 00000042 9039 LD R3, Y+ \ 00000044 91E9 LD R30, Y+ \ 00000046 91F9 LD R31, Y+ \ 00000048 9189 LD R24, Y+ \ 0000004A 9518 RETI 12 #pragma diag_default=Ta006 13 14 #pragma vector=TIMER1_OVF_vect
\ In segment CODE, align 2, keep-with-next 15 __raw __interrupt void I1(void) \ I1: 16 { 17 __enable_interrupt(); \ 00000000 9478 SEI 18 PORTB|=0x1; \ 00000002 9AC0 SBI 0x18, 0x00 19 ((void (*)(void))IntLong)(); \ 00000004 .... RCALL IntLong 20 } \ 00000006 9518 RETI
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|