|
发表于 2010-3-12 13:21:05
|
显示全部楼层
编译死机是编译器的事情……
对于“单片机不允许在中断里面调用函数”的情况,用宏插入实际的代码
就可以了。
不过,深入浅出中描述的这种做法,属于我过去的一种解决思路。
后来,我参考了很多别人的好的做法,意识到一个问题,中断处理程序的
处理方式,在可移植的框架中需要根据实际情况进行分类:
1、实时性要求高的情况下,尽可能使用宏插入代码的方法;如果编译器
会编译死机,应该考虑换一个编译器(不过我觉得多半换一个版本就
好了,因为基本的宏处理都有问题,编译器本身就是有BUG的)。
2、在实时性不高的情况下,可以参考下面的处理方式:
假设有一个宏
#if __IS_COMPILER_GCC__
#include <avr/interrupt.h>
#define REGISTER_ISR(__VECTOR, __ISR) \
extern void __ISR(void);\
ISR(__VECTOR)\
{\
__ISR();\
}
#elif __IS_COMPILER_IAR__
#ifndef PRAGMA
#define PRAGMA(__STRING) _Pragma(#__STRING)
#endif
#ifndef ISR
#define ISR(num) PRAGMA( vector = num ) __interrupt void isr_##num(void)
#endif
#define REGISTER_ISR(__VECTOR, __ISR) \
extern __task void __ISR(void);\
PRAGMA( vector = __VECTOR ) __interrupt void isr_##num(void)\
{\
__ISR();\
}
#endif
则,在最底层程序中,使用如下的代码来处理中断(比如 看门狗定时器中断)
#ifndef SLOW_TIMER_INTERRUPT_SERVICE_ROUTINES
#warning no defined SLOW_TIMER_INTERRUPT_SERVICE_ROUTINES, \
all accesses to slow timer will be ignored.
#if __IS_COMPILER_ICC__
#pragma interrupt_handler SLOW_TIMER_INTERRUPT_SERVICE_ROUTINES:iv_WDT
#elif __IS_COMPILER_GCC__ || __IS_COMPILER_IAR__
REGISTER_ISR(WDT_vect, SLOW_TIMER_INTERRUPT_SERVICE_ROUTINES)
#endif |
|