⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 int18xxx.h

📁 FreeRTOS 是一个源码公开的免费的嵌入式实时操作系统
💻 H
字号:
// INT18XXX.H:  saving and restoring registers during interrupt
/*
 IMPORTANT: CC8E will AUTOMATICALLY check that vital registers are
 saved and restored during interrupt. This applies to:

   Group 1:  W/WREG, STATUS, BSR  : most frequent used
   Group 2:  FSR0, FSR1, FSR2     : indirect access
   Group 3:  TBLPTR, TABLAT       : reading 'const' data
   Group 4:  PRODL, PRODH         : multiplication instructions
   Group 5:  PCLATH, PCLATU       : computed goto

 NOTE that it is not required to save registers before starting to
 service the interrupt. Section 'Custom interrupt save and restore',
 shows a list of instructions that that will not disturb the main
 registers.

 It is possible to limit the save and restore of a specific register
 to a small region inside the interrupt service routine, if this
 register is modified only inside this region.

 CC8E supports CUSTOM save and restore sequences. If you want to use
 your own register save and restore during interrupt, please read
 the following CUSTOM INTERRUPT SAVE AND RESTORE section.


// DEFAULT INTERRUPT STRUCTURE (RECOMMENDED)

   #include "int18XXX.h"

   void _highPriorityInt(void);

   #pragma origin 0x8
   interrupt highPriorityIntServer(void)
   {
       // W, STATUS and BSR are saved to shadow registers

       // handle the interrupt
       // 8 code words available including call and RETFIE
       _highPriorityInt();

       // restore W, STATUS and BSR from shadow registers
       #pragma fastMode
   }

   #pragma origin 0x18
   interrupt lowPriorityIntServer(void)
   {
       // W, STATUS and BSR are saved by the next macro.
       int_save_registers

       /* NOTE : shadow registers are updated, but will be
          overwritten in case of a high-priority interrupt.
          Therefore #pragma fastMode should not be used on
          low-priority interrupts. */

       // save remaining registers on demand (error/warning)
       //uns16 sv_FSR0 = FSR0;
       //uns16 sv_FSR1 = FSR1;
       //uns16 sv_FSR2 = FSR2;
       //uns8 sv_PCLATH = PCLATH;
       //uns8 sv_PCLATU = PCLATU;
       //uns8 sv_PRODL = PRODL;
       //uns8 sv_PRODH = PRODH;
       //uns24 sv_TBLPTR = TBLPTR;
       //uns8 sv_TABLAT = TABLAT;

       // handle the interrupt
       // ..

       // restore registers that are saved
       //FSR0 = sv_FSR0;
       //FSR1 = sv_FSR1;
       //FSR2 = sv_FSR2;
       //PCLATH = sv_PCLATH;
       //PCLATU = sv_PCLATU;
       //PRODL = sv_PRODL;
       //PRODH = sv_PRODH;
       //TBLPTR = sv_TBLPTR;
       //TABLAT = sv_TABLAT;

       int_restore_registers // W, STATUS and BSR
   }

   /* IMPORTANT : GIEH/GIE or GIEL should normally NOT be
      set or cleared in the interrupt routine. GIEH/GIEL are
      AUTOMATICALLY cleared on interrupt entry by the CPU
      and set to 1 on exit (by RETFIE). Setting GIEH/GIEL to
      1 inside the interrupt service routine will cause
      nested interrupts if an interrupt is pending. Too deep
      nesting may crash the program ! */


   void _highPriorityInt(void)
   {
       // save registers on demand

       // restore registers on demand
   }

 The compiler will detect if the initially mentioned registers are
 modified during interrupt processing without being saved and
 restored. The supplied macros for saving and restoring registers
 will only save W, STATUS and BSR. The other registers have to be
 saved and restored by user code when needed.

 For example, if FSR0 is modified by a table or pointer access, or
 by direct writing, the compiler will check that FSR0 is saved and
 restored, also in nested function calls. Note that the FSR0 saving
 and restoring can be done in a local region surrounding the indexed
 access, and does not need to be done in the beginning and end of
 the interrupt routine.

 A warning is printed if the Group 2 - 5 registers mentioned above
 are saved but not changed.

 The error and warning messages printed can be removed:

  #pragma interruptSaveCheck  n  // no warning or error
  #pragma interruptSaveCheck  w  // warning only
  #pragma interruptSaveCheck  e  // error and warning (default)

 Note that the above pragma also change the checking done on all
 registers.


// CUSTOM INTERRUPT SAVE AND RESTORE:

 It is not required to use the above save and restore macros. CC8E
 also supports custom interrupt structures.

  A) You may want to use your own save and restore sequence. This
     can be done by inline assembly. Take a look at the macros at
     the end of this file to get an idea on how to do this. If CC8E
     does not accept your code, just insert (on your own risk):

       #pragma interruptSaveCheck  n  // no warning or error

  B) No registers need to be saved when using the following
     instructions in the interrupt routine. The register save
     checking should NOT be disabled.

       btss(bx1);      // BTFSS 0x70,bx1  ; access RAM/SFR only
       bx2 = 1;        // BSF   0x70,bx2  ; access RAM/SFR only
       bx1 = 0;        // BCF   0x70,bx1  ; access RAM/SFR only
       bx3 = !bx3;     // BTG   0x70,bx3  ; access RAM/SFR only
       btsc(bx1);      // BTFSC 0x70,bx1  ; access RAM/SFR only
       vs = swap(vs);  // SWAPF vs,1      ; access RAM/SFR only
       vs = incsz(vs); // INCFSZ vs,1     ; access RAM/SFR only
       nop();          // NOP
       vs = decsz(vs); // DECFSZ vs,1     ; access RAM/SFR only
       clrwdt();       // CLRWDT
       a = b;          // MOVFF a,b       ; all RAM/SFR
       ..etc.          // CALL, GOTO, BRA, RCALL,..

  C) It is possible to enable interrupt only in special regions
     (wait loops) in such a way that main registers can
     be modified during interrupt without disturbing the main
     program. The register save can then be omitted and the save
     checking must be switched off to avoid the error messages:

       #pragma interruptSaveCheck  n  // no warning or error
*/


 #define  int_save_registers  \
    char svrSTATUS, svrBSR, svrWREG;  \
    svrSTATUS = STATUS;  \
    svrBSR = BSR; \
    svrWREG = W;

 #define  int_restore_registers \
    W = svrWREG;  \
    BSR = svrBSR;  \
    STATUS = svrSTATUS;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -