Перейти к содержанию
    

__raw прерывания

Если честно, я вобще не вникал в суть алгоритма/проблемы автора :)

На сахаре автар попросил не вникать :07:

 

А вобще как-то это все странно, 25 лишних тактов и уже мерцание...

 

Афтар, приведите минимальный код в котором будет эта проблема

 

http://caxapa.ru/90428.html + прерывание от адц с размешением в память 32 байт и выставлением флага.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот это пожалуйста поподробней!!! Так и пытался сделать но не пойму с синтаксисом (в С новичок). Не принимает он у меня jmp через функцию.

jmp на АСМе на абсолютный адрес где лежит jmp "фиктивного" обработчика(нужной С функции).

На С скорее всего такой трюк (jmp) описать не получится, тк нужно сохранять/восстанавливать

используемые для этого регистры

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

jmp на АСМе на абсолютный адрес где лежит jmp "фиктивного" обработчика(нужной С функции).

На С скорее всего такой трюк (jmp) описать не получится, тк нужно сохранять/восстанавливать

используемые для этого регистры

Получится, если фиктивное сделать без __raw. Не получается абсолютный адрес, нету такой, есть только относительный RJMP.

Если сделать так то и асма не нужно тк С код будет соизмерим. Но не вызывает он функции обозначенные как __interrupt!

Изменено пользователем Т.Достоевский

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

по Вашей ссылке прерывания ADC не увидел, дальше не копал

Получится, если фиктивное сделать без __raw.
Дык __raw подразумевает сохранение ручками

Если сделать так то и асма не нужно тк С код будет соизмерим. Но не вызывает он функции обозначенные как __interrupt!

конечно не вызывает, interrupt это не функция

там прокатит только абсолютный jmp

можете его в ASM обработчике через DB xx, xx написать

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В том то и дело, в меге нету абсолютного jmp!. Пытаюсь сделать как на асме, RJMP метка. Ассемблер сам вычисляет смещение. Вот и думаю как эту метку на С записать чтоб то-же сам вычислял.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ты и тут уже :-)

 

__indirect_jump_to((unsigned long)&Имя_функции);

 

Стек может испортиться, надо смотреть что компилятор наделает, и если что исправлять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ты и тут уже :-)

__indirect_jump_to((unsigned long)&Имя_функции);

 

Стек может испортиться, надо смотреть что компилятор наделает, и если что исправлять.

 

Вот это уже интерестней.

 

А Я везде, просто не знал что иар это игрушка

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот это уже интерестней.

 

А Я везде, просто не знал что иар это игрушка

не...,

inderect jump для прерываний не прокатит

скорее смотри на:

_OPC(opCode)

ну или что то же самое на __insert_opcode(opCode)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не...,

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");
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

__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");
}

все сохранять не нужно, а не все, тогда обработчик нельзя больше трогать, но скорее всего ПРИДЁТСЯ. В этом то и соль что придётся трогать не мне. Так бы я его на асме уже-б давно....

Изменено пользователем Т.Достоевский

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

все сохранять не нужно, а не все, тогда обработчик нельзя больше трогать, но скорее всего ПРИДЁТСЯ. В этом то и соль что придётся трогать не мне. Так бы я его на асме уже-б давно....

Все регистры сохранить "про запас" и обработчик больше не трогать. А "трогать" вашему коллеге "чистому Сишнику" нужно только лишь функцию funcBlaBlaBla.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

__indirect_jump_to((unsigned long)&Имя_функции);

__indirect_jump_to((unsigned long) 0x000001);

Не хочет у меня есть эти вещи. Но не ругается если просто __indirect_jump_to(unsigned long); Чего я опять не так делаю?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Незнаю

 

#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 }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не хочет у меня есть эти вещи. Но не ругается если просто __indirect_jump_to(unsigned long); Чего я опять не так делаю?
Подозреваю, что не включили заголовочный файл, в котором находится объявление функции __indirect_jump_to(). Изучайте, чем вызов функции отличается от ее объявления и чем объявление функции отличается от ее определения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делаю так обычно, ужос конечно, но что поделать:

 

в .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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...