关于ADSP-TigerSHARC的IDLE指令

手头有一本《ADSP技术与应用》(机械工业出版社),主要讲解SHARC系列。我在书中P58看到待机指令IDLE,对它的说明如下:
 

    DSP进入低功耗等待状态,程序地址不变,直到某个中断出现才执行中断服务程序和后续指令。
      降低功耗,这个比较诱人,因为很多场合电量的提供非常有限。
     上面所说是SHARC的IDLE指令,在TigerSHARC中又如何呢?我在ADSP-TS201 TigerSHARCProcessor Programming Reference中找到下面这段话:
      This instruction causes theTigerSHARC processor to go into IDLE state. In this state theTigerSHARC processor stops executing instructions and waits for anytype of interrupt.
     这段文字说得相当明确,虽然没有说可以降低功耗,但是处理器停止执行指令(...Processor stops executinginstructions...),功耗肯定会下降一些吧。
      为了试验一下这条指令,我写了如下的C程序:


#include <builtins.h>
#include <sysreg.h>
#include <defts201.h>

const char __argv_string[] = "-abc -xyz";

#define IDLE __builtin_idle()
#define RREAD(reg) __builtin_sysreg_read(reg)
#define RWRITE(reg,value) __builtin_sysreg_write(reg,value)

void irq0_isr(void);

int main( int argc, char*argv[] )
{
   
    int v;
    //将FLAG2设为输出模式
   RWRITE(__FLAGREGST,FLAGREG_FLAG2_EN);
    //设置IRQ0服务程序
   RWRITE(__IVIRQ0,(int)irq0_isr);
    //设置跳沿触发
   RWRITE(__INTCTL,0);
    //允许外部IRQ0
   v=RREAD(__IMASKH);
   v|=(1<<INT_IRQ0_P);
    RWRITE(__IMASKH,v);
    //开全局中断使能
   RWRITE(__SQCTLST,SQCTL_GIE);
    v=0;
    IDLE;//调用__builtin_idle()
   v=0;
    return 0;
}

#pragma interrupt
void irq0_isr(void)
{
    static intbutton=0;
    button=!button;
    if(0==button)
    {
       RWRITE(__FLAGREGCL,~FLAGREG_FLAG2_OUT);
    }
    else
    {
       RWRITE(__FLAGREGST,FLAGREG_FLAG2_OUT);
    }
}

      在main函数中的IDLE(注意main函数中的那个IDLE不是汇编指令IDLE,而是我自己定义的一个宏,用来调用__builtin_idle)和return0中间的那句v=0设置一个断点,然后用EZ-KIT运行程序,我们会发现VisualDSP++的状态栏一直显示Running而不会到达断点。如果我们通过按钮触发一个IRQ0,则与FLAG2管脚相连的LED发光(表明中断服务程序被执行),程序马上就到达断点处,验证了执行IDLE指令时DSP的行为。
     函数__builtin_idle就是用来在程序中加入IDLE指令,看一下反汇编就明白了。  

     这样看来,如果我们的DSP程序主要任务都是由中断来触发的话,在main中的那个死循环写成while(1);就是不经济的了,如果写成:
while(1)
    __builtin_idle();
      是否能变得省电呢?应该会吧。可惜手头没有什么仪器测试一下功耗。

     在51及其兼容单片机中,没有IDLE这样的指令,如果程序的任务都是由中断触发,则主程序在完成初始化的任务之后,就会用一句SJMP$进行原地跳转。如果用C51,就写while(1);或for(;;);这两种写法对应的汇编都是一样的:

while(1);的汇编代码:

    58:    while(1);
C:0x0040   80FE     SJMP    C:0040

for(;;);的汇编代码:

   59:        for(;;);
C:0x0040   80FE     SJMP    C:0040

     上面汇编代码SJMP前面的80FE就是对应的机器代码。SJMP指令由两个字节组成,第一个字节是80H,表示它是SJMP指令,第二个字节是一个有符号的整数,表示相对偏移量。这条指令是这样被执行的:

      首先PC加2,因为这条指令有两个字节;

     然后把第二个字节表示的相对偏移量加到PC上,作为下一条指令的地址。

      SJMP$对应的机器码是80FE,因为FE是补码形式,对FE取反得到01,然后加一,得到2,于是FE表示-2。指令80FE就是先让PC+2,然后将PC-2,这一加一减,所以PC仍然指向SJMP$,原地跳转。

 

    可见,没有类似IDLE指令的51及其兼容单片机,在等待中断的时候,依然不停地取指令,执行指令。


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值