|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统 驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe |
举例说明PICC是如何保护现场的 |
作者:cf100 栏目:单片机 |
大家来看一下具体的例子,用PIC16F887A编译下列程序。 第一次,中断处理函数什么也不做。 #include "pic.h" unsigned int m,n; unsigned CHAR i,j,k,l; void interrupt SAMPLE (void) { } void main(void) { } 因为不进行操作,中断函数不需要进行现场保护,编译后结果是直接返回。 0004 0009 retfie 第二次, 中断处理函数增加一条对全局变量的操作。 void interrupt SAMPLE (void) { i++; } 编译结果是: 0004 00F0 movwf saved_w 0005 0803 movf 3,w 0006 0183 clrf 3 0007 00A8 movwf saved_status 0008 0183 clrf 3 0009 0AA0 incf _i 000A 0828 movf saved_status,w 000B 0083 movwf 3 000C 0EF0 swapf saved_w 000D 0E70 swapf saved_w,w 000E 0009 retfie 从结果看,只保护W和STATUS,不对全局变量进行现场保护。 最后来看一个中断处理函数中调用一个函数fn()的例子。 在fn()函数中涉及全局变量和局部变量。 void fn(void) { CHAR TEMP; TEMP=i+j; i=TEMP++; } void interrupt SAMPLE (void) { fn(); } 0004 int_entry 0004 00F0 movwf saved_w 0005 0803 movf 3,w 0006 0183 clrf 3 0007 00A9 movwf saved_status 0008 080A movf 10,w 0009 00AA movwf saved_pclath 000A 018A clrf 10 000B 120A ISR BCF PCLATH,0X4 000C 118A BCF PCLATH,0X3 000D 27F9 CALL fn 000E 120A BCF PCLATH,0X4 000F 118A BCF PCLATH,0X3 0010 082A movf saved_pclath,w 0011 008A movwf 10 0012 int_restore 0012 0829 movf saved_status,w 0013 0083 movwf 3 0014 0EF0 swapf saved_w 0015 0E70 swapf saved_w,w 0016 0009 retfie 在第三个例子中,由于涉及到跨页的问题,中断函数为了能正确返回中断发生处地址,对PCLATH进行保护。 从以上我们可以看出,无论是在中断处理中使用的变量,还是在中断处理中调用其它函数而使用的变量,中断函数都不会对其实行自动保护。 当然中断前的地址入栈是属于硬件功能,不需要软件中作出相应操作。 |
2楼: | >>参与讨论 |
作者: xieyuanbin 于 2005/1/25 18:19:00 发布:
看来CF100花了不少工夫,加裤! |
3楼: | >>参与讨论 |
作者: 手扶拖拉机 于 2005/1/25 22:30:00 发布:
顶! 这个论坛要是每个人都能如cf100一样总结一些东西,就不怕大家的水平上不去! |
4楼: | >>参与讨论 |
作者: eyuge2 于 2005/1/26 10:55:00 发布:
谢谢 感谢cf100的帮助。 你精英联盟中给我回复时引用的一段摘自PICC说明书的话,这个PICC说明书好像版本比较特别哦,不是张明峰的,也不是伟福的,能不能拿出来共享一下? |
5楼: | >>参与讨论 |
作者: mikezhong 于 2005/1/26 12:35:00 发布:
CF100大侠也! CF100大侠也! 摘自的就是张明峰的断落。 |
6楼: | >>参与讨论 |
作者: 笨蛋不笨 于 2005/1/26 17:03:00 发布:
敬业!! |
7楼: | >>参与讨论 |
作者: eyuge2 于 2005/1/27 8:30:00 发布:
cf100老师,继续哦! cf100老师可否再将下面的话考证一下,好人做到底嘛! 避免在中断内进行数学运算。数学运算将很有可能用到库函数和许多中间变量,就 算不出现递归调用的问题,光在中断入口和出口处为了保护和恢复这些中间临时变 量就需要大量的开销,严重影响中断服务的效率。 |
8楼: | >>参与讨论 |
作者: cf100 于 2005/1/27 17:21:00 发布:
继续讨论PICC保护现场的问题 以下这段话表达的意思也不很贴切: 光在中断入口和出口处为了保护和恢复这些中间临时变 量就需要大量的开销,严重影响中断服务的效率。 其实,在PICC中,对中断中使用的临时变量,为了防止重入或覆盖,干脆就是中断专用。 在我们的PICC编程中,临时变量(或者说局部变量),都有其生存期,在生存期结束后,可被覆盖。 但中断函数中使用到的临时变量却与一般概念上的临时变量有很大的区别。中断函数中使用到的临时变量和中断函数中不使用到的临时变量不能占用同一地址。换言之,中断和非中断的临时变量地址不得重叠。 看一下下面的例程:(16F877A) #include "pic.h" unsigned CHAR i,j,k; void fn1(void) { unsigned CHAR s1[40]; s1[0]=1; } void interrupt SAMPLE (void) { unsigned CHAR s2[50]; s2[0]=1; fn1(); } void main(void) { } 说明:i,j,k-----三个全局变量 s1[40]----40个中断调用使用的临时变量 s2[50]----50个中断中使用的临时变量 保护W、STATUS和PCLATH用去三个内存变量 从上面程序中可以看出,BANK0资源已经耗尽。50+40+3+3=96。 由于中断使用了93个RAM,这样中断以外就没有可以使用的临时变量了。也就是说中断使用的临时变量将不会被重入。 再看一下下面的例子: #include "pic.h" unsigned CHAR i,j,k; void fn1(void) { unsigned CHAR s1[20]; s1[0]=1; } void fn2(void) { unsigned CHAR s3[20]; s3[0]=1; } void interrupt SAMPLE (void) { unsigned CHAR s2[50]; s2[0]=1; fn1(); } void main(void) { fn2(); } 说明:i,j,k-----三个全局变量 s1[20]----20个中断调用使用的临时变量 s2[50]----50个中断中使用的临时变量 s3[20]----20个非中断使用的临时变量 保护W、STATUS和PCLATH用去三个内存变量 从上面的例子中也可以看出,中断使用的临时变量和中断外使用的临时变量不可重叠。 eyuge2兄所说的PICC自动保护现场,其实就是PICC对中断中使用的临时变量实施“禁入”。也就是,中断内可实施中断内临时变量覆盖;中断外的临时变量也可进行覆盖;但中断内外之间的临时变量不可相互覆盖。 当然为了防止重入,中断中使用的函数不可在中断外被调用。(PICC可自动实施重入检查。) |
9楼: | >>参与讨论 |
作者: eyuge2 于 2005/1/28 17:43:00 发布:
非常感谢cf100老师 谢谢。 picc中自动变量可以相互重叠,但是必须保证定义这些自动变量的函数不能同时调用。中断函数可以被看作是用比较特殊的函数,它可能在任何时候被调用,从而可能发生“嵌套”,形成同时调用。故中断函数中的自动变量和其他函数中的自动变量是不能重叠的。中断中使用的函数不可在中断外被调用,同样也是这个道理,因为会产生“递归”。不知理解的是否正确? cf100老师关于你阐述的东东是否有参考书目之类的东西推荐? |
10楼: | >>参与讨论 |
作者: cf100 于 2005/1/28 18:11:00 发布:
eyuge2 兄说的就是这个道理 因为PIC的特殊性,不许重入,所以和别的C编译器就有很大的区别。 也没什么参考书目可看的,不过PICC的自动保护功能还是够全的,足以保证程序不发生重入。 |
11楼: | >>参与讨论 |
作者: jiangl 于 2005/2/19 9:03:00 发布:
顶 支持 |
12楼: | >>参与讨论 |
作者: fleas 于 2005/2/21 11:58:00 发布:
以前还真不知道不能重入这个概念 看来比较不方便啊 |
|
|
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入 |
Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号 |