请选择 进入手机版 | 继续访问电脑版

EDABOSS电子论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1080|回复: 1

[转帖] DM64X 中断响应延时问题

[复制链接]

141

主题

15

回帖

368

E币

助理工程师

Rank: 3Rank: 3

积分
297
发表于 2017-4-19 16:05:25 | 显示全部楼层 |阅读模式
问题描述:
  系统硬件中断经常得不到及时响应,根据现象推断中断会被延迟达150us以上。
分析过程:
  开始以为是有其他中断打断或占用CPU。但经过实验验证发现这种延迟并非受中断影响,而是和任务有关。
最终确认这种延时和某个任务中的memset调用有关。将这个函数注释掉就可以明显减小中断延迟发生的频率。
memset(buffer,0,lenth);
  由于片内空间不足,buffer位于片外SDRAM
  于是先怀疑这个函数可能对中断机制做了什么禁止操作,便用自己写的for循环代替memset函数进行清0操作,并且进行9次。
for(j=0;j<9;j++){
dst=buffer;
       for (len=0;len<38400;len++){
       *dst++ = 0;
       }
}
  从示波器可以看到连续9个中断响应都被延迟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 GuideSPRU732H)。第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无法中断而继续下一次循环。直到循环结束才开始响应中断。
解决方法:
  可以使用DMA操作,用DAT_fill()函数代替memset()函数。
  可以将较长的for循环分解为多层for循环,以减小最内层for循环执行时间,减小对中断的影响。内层循环结束后可以适当做一点简单的运算来提供5周期的“空隙”。
  可以用64位操作或32位操作替换8位操作,可减小赋值所需的总时间。
  TI有专门的编译指令来强制打断这种循环,以使中断得到响应。
SPRU198G文档interrupts节内有相关描述。

  其实这不算是问题,而是DM64X系列内核的结构特性。为使CPU的效率更高,对中断处理的实时性做了一些折衷。不过,此处需格外注意。如果设计中发现中断未及时响应,可以用我描述的方法来定位是哪里影响到了中断执行。

积分规则
回复

使用道具 举报

141

主题

15

回帖

368

E币

助理工程师

Rank: 3Rank: 3

积分
297
 楼主| 发表于 2017-4-19 16:05:45 | 显示全部楼层
问题描述:
系统调试过程中发现硬件中断经常得不到及时响应,根据现象推断中断会被延迟达150us以上。
问题分析:
中断信号是连到CPLD的,DSPGPIO6也与CPLD相连。用CPLD的任一个输出脚IOX做为中断延迟指示。中断沿来了之后将IOX置为高电平,DSP进入中断服务函数马上给GPIO6一个翻转,CPLD检查到来自GPIO6的翻转后将IOX清为低电平。这样,通过观察IOX上的信号正脉冲宽度就可以看到从中断发生到中断得到响应所用的时间了。而且通过脉宽触发模式就可以设置大于150us的正脉冲触发,这样就能捕捉到异常情形了。通过测试发现,一般延迟只有400ns左右,但任务负载一重就会出现宽度超过150us的正脉冲,也就是中断被延迟了150us以上才得到响应。
下图为观察到的IOX管脚上的波形:
48191932991621.jpg


开始以为是有其他中断打断而占用CPU。但经过实验验证发现这种延迟并非受中断影响,而是和任务有关。
最终确认这种延时和某个任务中的memset()函数调用有关――这个函数对片外SDRAM中的384×100个字节进行清0操作。将这个函数注释掉就可以明显减小中断延迟发生的频率。
memset(buffer,0,lenth);
由于片内空间不足,buffer位于片外SDRAMlenth384×100
于是先怀疑这个函数可能对中断机制做了什么禁止操作,便用自己写的for循环代替memset函数进行清0操作,看是不是会解决这个问题。后来却发现延迟反而更长了。于是将for循环多进行几遍,编程使for循环重复9次。
for(j=0;j<9;j++){
dst=buffer;
       for (len=0;len<38400;len++){
       *dst++ = 0;
       }
}
从示波器可以看到连续9个中断响应异常:
48191932960332.jpg


上面的波形即可看出,中断发生是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 GuideSPRU732H)。第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位操作,可减小赋值所需的总时间。
可以用编译器的“-mi”编译项来让编译器自动处理(后面需带参数,具体意义和用法可参见TISPRU198G文档“TMS320C6000 Programmer’s Guide”的“interrupts”一节,356页)。
注:64x64x+都是这样的。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|EDABOSS电子论坛

GMT+8, 2024-3-28 20:09 , Processed in 0.044288 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表