中断发生是200us周期的,超过200us的中断延迟会致使一次中断丢失。这几个异常中断响应之间(脉冲下降沿间隔)都是300us.,于是推断一次内循环大致耗时300us。
更改次数为5,则可以见到连续5个中断响应都被延迟300us左右。如果按133M写速率的话,这个时间刚好是38400/133M=288us。于是怀疑为for循环内中断一直不能得到响应。
在for循环内设置断点观察。发现for循环运行中,GIE有效,IER内的中断使能有效,IFR中断对应位也正常置1,但程序不会跳转到中断服务程序。直到内层的for循环结束后,才会跳转到中断服务程序,外层的for循环是可以打断的。因为自身的IER仍有效,所以判断没有进入HWI_enter调试程序,不是DSP/BIOS的问题。应当是DSP芯片循环赋值硬件机制和中断配合的问题。
上面的赋值语句是按字节赋值,DSP处理时每循环一次2个时钟周期,每循环一次写3个字节(多逻辑单元并行操作)。也许正是这种多逻辑单元并行处理机制导致的CPU不能即时响应中断。
后来在TI的一篇文档中找到了答案。TMS320C64x/C64x+ DSP CPU and Instruction Set Reference Guide(SPRU732H)。第534页列出了中断得到CPU响应需具备的条件。
· IFm is set during CPU cycle 6. (This determination is made in CPU cycle 4 by the interrupt logic.)
· There is not a higher priority IFm bit set in IFR.
· The corresponding bit in IER is set (IEm = 1).
· GIE = 1
· NMIE = 1
· The five previous execute packets (n through n + 4) do not contain a branch (even if the branch is not
taken).
其中第6条即标明,CPU响应中断前5个执行包内,不能有跳转指令。(execute packets指同一周期内可并行执行的指令集合——最多一周期可执行8条指令。)因为循环赋值的for循环内只有五六条汇编指令,往往在二到三个周期内即可完成一次循环,然后CPU无法中断而继续下一次循环。直到循环结束才开始响应中断。而从内层的for循环到下一次循环之间则刚好多于5个执行包,所以外层的for循环可以被中断
解决方法:
可以使用DMA操作,用DAT_fill()函数代替memset()函数。
可以将较长的for循环分解为多层for循环,以减小最内层for循环执行时间,减小对中断的影响。内层循环结束后可以适当做一点简单的运算来提供5周期的“空隙”。
可以用64位操作或32位操作替换8位操作,可减小赋值所需的总时间。