快乐虾
http://blog.csdn.net/lights_joy/
lights@hb165.com
本文适用于
ADI bf561 DSP
uclinux-2008r1.5-rc3(smp patch)
Visual DSP++ 5.0(update 5)
欢迎转载,但请保留作者信息
当发生系统中断时,将进入所指定的中断入口执行,在大部分情况下,需要对SP指针进行保存,然后将SP指向一个临时的位置,然后将寄存器入栈,再进行中断处理,在中断处理的最后恢复SP指针并返回中断前的位置继续执行。
那么选择什么位置来保存SP指针呢?内核提供了三个选择:
#if defined(CONFIG_BFIN_SCRATCH_REG_RETN)
# define EX_SCRATCH_REG RETN
#elif defined(CONFIG_BFIN_SCRATCH_REG_RETE)
# define EX_SCRATCH_REG RETE
#else
# define EX_SCRATCH_REG CYCLES
#endif
即可以选择RETN,RETE和CYCLES三个寄存器中的一个做为保存SP的位置,但实际上RETE这个寄存器本身就是一个需要进行入栈保存的东西,用它来保存SP,显然是荒谬的!
再看CYCLES寄存器,在不定义CONFIG_BFIN_SCRATCH_REG_RETN和CONFIG_BFIN_SCRATCH_REG_RETE两个宏情况下,将选择CYCLES来保存SP,但不幸的是在head.s中是这样设置SYSCFG的:
#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
R0 = SYSCFG_SNEN;
#else
R0 = SYSCFG_SNEN | SYSCFG_CCEN;
#endif
SYSCFG = R0;
也就是说,在不定义CONFIG_BFIN_SCRATCH_REG_CYCLES的情况下是会启用CYCLES寄存器进行计数的,在这种情况下显然不能使用它来保存SP。这就是它们矛盾的地方,head.s要求显示定义CONFIG_BFIN_SCRATCH_REG_CYCLES来使用CYCLES保存SP,而entry.s则与此相反!当然,内核通过make config保证了最终会定义三个宏中的一个,只是在代码风格上有点瑕疵罢了!
因此,如果在硬件上没有使用NMI中断,使用RETN当然是最好的选择了,呵呵!
1 参考资料
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(68):PLL配置(2009-02-16)
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(69):SHARED_MEMORY(2009-02-20)
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(70):保留VDSP的heap(2009-02-20)
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(71):l1_data_sram_init的疑惑(2009-02-20)