fmdost 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба Если честно, я вобще не вникал в суть алгоритма/проблемы автора :) На сахаре автар попросил не вникать :07: А вобще как-то это все странно, 25 лишних тактов и уже мерцание... Афтар, приведите минимальный код в котором будет эта проблема http://caxapa.ru/90428.html + прерывание от адц с размешением в память 32 байт и выставлением флага. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба Вот это пожалуйста поподробней!!! Так и пытался сделать но не пойму с синтаксисом (в С новичок). Не принимает он у меня jmp через функцию. jmp на АСМе на абсолютный адрес где лежит jmp "фиктивного" обработчика(нужной С функции). На С скорее всего такой трюк (jmp) описать не получится, тк нужно сохранять/восстанавливать используемые для этого регистры Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fmdost 0 12 июня, 2007 Опубликовано 12 июня, 2007 (изменено) · Жалоба jmp на АСМе на абсолютный адрес где лежит jmp "фиктивного" обработчика(нужной С функции). На С скорее всего такой трюк (jmp) описать не получится, тк нужно сохранять/восстанавливать используемые для этого регистры Получится, если фиктивное сделать без __raw. Не получается абсолютный адрес, нету такой, есть только относительный RJMP. Если сделать так то и асма не нужно тк С код будет соизмерим. Но не вызывает он функции обозначенные как __interrupt! Изменено 12 июня, 2007 пользователем Т.Достоевский Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба по Вашей ссылке прерывания ADC не увидел, дальше не копал Получится, если фиктивное сделать без __raw. Дык __raw подразумевает сохранение ручками Если сделать так то и асма не нужно тк С код будет соизмерим. Но не вызывает он функции обозначенные как __interrupt! конечно не вызывает, interrupt это не функция там прокатит только абсолютный jmp можете его в ASM обработчике через DB xx, xx написать Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fmdost 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба В том то и дело, в меге нету абсолютного jmp!. Пытаюсь сделать как на асме, RJMP метка. Ассемблер сам вычисляет смещение. Вот и думаю как эту метку на С записать чтоб то-же сам вычислял. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slog 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба Ты и тут уже :-) __indirect_jump_to((unsigned long)&Имя_функции); Стек может испортиться, надо смотреть что компилятор наделает, и если что исправлять. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fmdost 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба Ты и тут уже :-) __indirect_jump_to((unsigned long)&Имя_функции); Стек может испортиться, надо смотреть что компилятор наделает, и если что исправлять. Вот это уже интерестней. А Я везде, просто не знал что иар это игрушка Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба Вот это уже интерестней. А Я везде, просто не знал что иар это игрушка не..., inderect jump для прерываний не прокатит скорее смотри на: _OPC(opCode) ну или что то же самое на __insert_opcode(opCode) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба не..., 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"); } Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fmdost 0 12 июня, 2007 Опубликовано 12 июня, 2007 (изменено) · Жалоба __indirect_jump_to((unsigned long)&Имя_функции); Уиточни пожалуйста мнемонику. Особенно если вместо имя функции прямой адрес. А то я уже час буквы гоняю. В ИАР же вроде стандартная Сишная директива 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"); } все сохранять не нужно, а не все, тогда обработчик нельзя больше трогать, но скорее всего ПРИДЁТСЯ. В этом то и соль что придётся трогать не мне. Так бы я его на асме уже-б давно.... Изменено 12 июня, 2007 пользователем Т.Достоевский Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба все сохранять не нужно, а не все, тогда обработчик нельзя больше трогать, но скорее всего ПРИДЁТСЯ. В этом то и соль что придётся трогать не мне. Так бы я его на асме уже-б давно.... Все регистры сохранить "про запас" и обработчик больше не трогать. А "трогать" вашему коллеге "чистому Сишнику" нужно только лишь функцию funcBlaBlaBla. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fmdost 0 12 июня, 2007 Опубликовано 12 июня, 2007 · Жалоба __indirect_jump_to((unsigned long)&Имя_функции); __indirect_jump_to((unsigned long) 0x000001); Не хочет у меня есть эти вещи. Но не ругается если просто __indirect_jump_to(unsigned long); Чего я опять не так делаю? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slog 0 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Незнаю #pragma vector = TIMER0_OVF0_vect __interrupt __raw void T0ovf(void) { PORTA=tmp; __indirect_jump_to(0x0001); } компилируется в (листинг) 21 __interrupt __raw 22 void T0ovf(void) \ T0ovf: 23 { \ 00000000 REQUIRE ?Register_R15_is_global_regvar 24 PORTA=tmp; \ 00000000 BAFB OUT 0x1B, R15 25 __indirect_jump_to(0x0001); \ 00000002 E0E1 LDI R30, 1 \ 00000004 E0F0 LDI R31, 0 \ 00000006 9409 IJMP 26 } Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Не хочет у меня есть эти вещи. Но не ругается если просто __indirect_jump_to(unsigned long); Чего я опять не так делаю?Подозреваю, что не включили заголовочный файл, в котором находится объявление функции __indirect_jump_to(). Изучайте, чем вызов функции отличается от ее объявления и чем объявление функции отличается от ее определения. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Делаю так обычно, ужос конечно, но что поделать: в .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 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться