原创 Cy_OS 之系统启动 及中断响应

2008-7-30 23:42 4383 9 9 分类: MCU/ 嵌入式

在做这个的时候,曾别出心裁地要去掉keil c51一般加上的STARTUP.A51文件,就设计了一个初始化的C函数,采用嵌入汇编来写,把RESET的首地址也当一个中断来处理,然后利用keil 的绝对定位把该C函数设置成复位后第一个执行的函数,其内容如下:
void ISRAdrFun (void)  REENTRANT
{
#pragma asm
    NOP    //3
    NOP
    NOP
    NOP    //6
    NOP
    NOP
    NOP
    NOP    //0A


    LJMP SysTimer0 //0B
;    NOP
;    NOP
    NOP
    NOP
;;//////////////////////////////////
    NOP    //10
    NOP
    NOP
    NOP
    NOP
    NOP


    NOP
    NOP
    NOP
    NOP
    NOP    //1A


    NOP    //1B
    NOP
    NOP
    NOP
    NOP
;;//////////////////////////////////
    NOP    //20
    NOP
    NOP
    LJMP UartISR  //23
;    NOP
;    NOP


    NOP
    NOP
    NOP
    NOP
    NOP    //2A


    NOP    //2B
    NOP
    NOP
    NOP
    NOP
;;//////////////////////////////////
    NOP    //30
    NOP
    NOP
    LJMP IR_CaptureInt6  //33
;    NOP
;    NOP


    NOP
    NOP
    NOP
    NOP
    NOP    //3A


    NOP    //3B
    NOP
    NOP
    NOP
    NOP
;;//////////////////////////////////
    NOP    //40
    NOP
    NOP
    NOP   
    NOP
    NOP


    NOP
    NOP
    NOP
    NOP
    NOP    //4A


    NOP    //4B
    NOP
    NOP
    NOP
    NOP
#pragma endasm
}


//任意一个中断的入口都在自己的手中掌握了,在中断响应时所有的处理也由自己来完成,不会被keil给优化添加了,


于是我又写了两个中断的堆栈处理宏,用以在中断函数中调用,其源码如下:(注意两个进出顺序别搞错了)


#pragma asm
;/////////////////////////////////////////////////
;////////add by walnutcy 2006-11-22
;    PUBLIC  PUSHALL   出栈
PUSHALL MACRO
;;;;;;;;;;;;;;;;;;;;;;
     PUSH ACC  
     PUSH B  
     PUSH PSW  
     MOV PSW,#0x00
     PUSH DPL  
     PUSH DPH  
     PUSH 0x00 
     PUSH 0x01 
     PUSH 0x02 
     PUSH 0x03 
     PUSH 0x04 
     PUSH 0x05 
     PUSH 0x06 
     PUSH 0x07 
;;;;;;;;;;;;;;;;;;;;;;;;;;  
        ENDM


POPALL MACRO道  ;;入栈
;;;;;;;;;;;;;;;;;;;;
  POP  0x07
  POP  0x06
  POP  0x05
  POP  0x04
  POP  0x03
  POP  0x02
  POP  0x01
  POP  0x00
  POP  DPH
  POP  DPL
  POP  PSW
  POP  B  
  POP  ACC      
;;;;;;;;;;;;;;;;;;;;;;;;
  ENDM
;/////////////////////////////////////////////////
#pragma endasm


于是中断函数就可以按下边的格式写了:并注意将UartISR 在启动函数的对应中断位置注册


void UartISR (void) //interrupt 4
{
      U8 tmp;
#pragma asm
     PUSHALL
#pragma endasm 
     gOsIntLevel++;
    if (RI)// receive
   {  
         RI = 0;
         tmp = SBUF;
         SRL_RevChar(tmp);
   }
  OsIntExit();
  if (gOsIntLevel)
       gOsIntLevel--; 
#pragma asm
     POPALL
     RETI
#pragma endasm
}


现在想来,当初的设计真是麻烦,把工具的优势去掉了,再拿一个小的不再小,资源少得不能再少的芯片在那模拟任务切换,学习现场保护机制,其实应该直接找个ARM板学习学习uCOS-II的切换机理。


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条