walnutcy

Cy_OS 之系统启动 及中断响应

0
阅读(3878)

在做这个的时候,曾别出心裁地要去掉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的切换机理。
Baidu
map