斑竹,把中断的外壳和中断处理程序分家不好移植啊。
深入浅出书中描述:把中断外壳留在硬件初始化里,实际的中断处理函数放在硬件驱动函数里面.
再通过定义"宏"为中介把中断函数插进来,把宏展开的代码就是XXXXX();
中断函数的调用了,但是很多单片机不允许在中断里面调用函数啊,如合泰/PIC等.
我在CVAVR里试过也不行.一编译就死机.直接把代码写在中断函数里面就OK.
这阵子都在研究怎么实现"硬件无关性"感觉好困难,郁闷哪. 编译死机是编译器的事情……
对于“单片机不允许在中断里面调用函数”的情况,用宏插入实际的代码
就可以了。
不过,深入浅出中描述的这种做法,属于我过去的一种解决思路。
后来,我参考了很多别人的好的做法,意识到一个问题,中断处理程序的
处理方式,在可移植的框架中需要根据实际情况进行分类:
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 希望对你有所启发。
另外,中断处理程序属于不易移植的部分,对其考虑通用,通常得不偿失。
用注释把核心代码记录下来,不同平台下根据实际情况来具体实现这些“核心代码”
才是王道。
HAL 层封装以后,外界应该没有中断这个概念了,只剩下service。如果外界还有
中断这样的概念,说明封装不到位,而且代码移植可能会遇到困难。 谢谢!!!
页:
[1]