原创 MPLAB C18 3.03版本的中断现场保护(和以前的版本有所改变)

2010-4-15 10:07 3164 13 13 分类: MCU/ 嵌入式
在通常情况下, MPLAB C18基本的现场保护,编译器会自动产生代码保护编译器自动管理的资源。这些资源包括以

下内容:

WREG - 主要用途:中间计算

STATUS - 主要用途:计算结果

BSR - 主要用途:BANK选择

FSR0 - 主要用途:RAM的指针

FSR1 - 主要用途:堆栈指针

FSR2 - 主要用途:堆栈的帧指针

PROD  - 主要用途:乘积结果,16位的函数返回值(借用),计算的中间变量(借用)

临时数据段 .tmpdata - 主要用途,计算的中间变量(注:当编译器中断保护现场时,不会保存任何使用#pragma

tmpdata伪指令来创建的临时数据段,编译器只会保存默认的临时数据段。)

TBLPTR - 主要用途:访问程序空间的值(注:在small memory model时,TBLPTRU被自动保护是因为在中断服务程

序里使用到了TBLPTRU,不是因为在中断里有函数调用。但是,在large memory model时,中断里使用到了TBLPTRU

或者中断里有函数调用,都会自动保护TBLPTRU。)

TABLAT - 主要用途:访问程序空间的值

PCLATH - 函数指针援引

PCLATU - 函数指针援引(注:在small memory model时,PCLATU被自动保护是因为在中断服务程序里使用到了它

,不是因为在中断里有函数调用。但是,在large memory model时,中断里使用到了PCLATU或者中断里有函数调用

,都会自动保护PCLATU。)

数据段 MATH_DATA - 数学运算库函数使用的参量,返回值和一些临时位置

如果主函数使用的某变量在中断里也会对他改动的,并有可能造成主函数里出错的,这些变量可能需要作为额外的

现场保护,此时需要使用save=字句,如:
要保存一个名为myint 的用户定义全局变量,使用如下pragma 伪指令:
#pragma interrupt high_interrupt_service_routine save="myint"

除了对某个变量额外保护,也可以在save= 子句来保护整个数据段。比如,要在中断现场保护时保存一个自己定义

的名为mydata的数据段时,可以使用如下pragma 伪指令:
#pragma interrupt high_interrupt_service_routine save="section"("mydata")

如果上面的两个都需要额外保护,可以用逗号隔开,如下:
#pragma interrupt isr save="myint", section("mydata")

指定资源仅用于中断
由于某些应用程序仅将编译器保存的存储单元用于中断现场,因此不必主动地保存和恢复这些存储单元的值。

nosave= 子句允许将编译器管理的资源指定为仅用于中断服务程序 ,因此可以不跨中断主动保存这些资源。对于高

优先级中断, nosave= 子句中指定的存储地址可以是如下之一: FSR0、TBLPTR、TBLPTRU、TABLAT、
PCLATH、PCLATU、PROD、section(“.tmpdata”) 或section(“MATH_DATA”)。对于低优先级中断, nosave= 子句可以

指定高优先级中断的任一存储地址或以下寄存器之一:WREG、BSR 或 STATUS。而且,当为扩展模式
编译时,编译器还接受__RETVAL0 作为MATH_DATA 段的参考。例如,要指定将TBLPTR 和TABLAT 寄存器仅用于高优

先级中断函数foo 的现场,因而不需要由编译器保存和恢复这两个寄存器,将使用下面的pragma 伪指令:
#pragma interrupt foo nosave="TBLPTR", TABLAT

当编译器为ISR 保护现场时,即使已经用#pragma tmpdata伪指令为ISR调用的函数指定了不同的临时数据段,编译

器也将自动保存默认临时数据段.tmpdata。为了告知编译器不要增加.tmpdata 段的现场保护开销,可在中断的

#pragma 伪指令中使用nosave=子句,如下例:
//本例中,中断服务程序isr 和非中断函数increment 的编译器临时变量都存放在udata 段isr_tmp 中。
void increment (int counter);
void isr (void);
#pragma interrupt isr nosave="section"(".tmpdata")//所以这里不需要再保存默认的.tmpdata数据段了
void isr (void)
{
static int foo = 0;
...
increment (foo);
...
}
#pragma tmpdata isr_tmp   
void increment (int counter)
{
...
}
#pragma tmpdata

转载请注明出处:www.picpic.cn
Martin 2006/6/27

 

PARTNER CONTENT

文章评论0条评论)

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