在 CAPL 中使用 while 会导致软件在模拟运行时开始时冻结

问题描述 投票:0回答:1

在Canoe中模拟运行时,软件冻结,我认为这是暂时的原因。但是,在while代码段中,我写了停止循环的逻辑,不知道为什么……………… ...................................................... ...................................................... ………………

这是我的代码。

/*@!Encoding:936*/
includes
{
  
}

variables
{
   timer time1;
   int status;
   int idx;
   message 0x1 msg;
}

on preStart
{
    sysSetVariableInt(sysvar::Mynamespace::LockSign,0);
    write("begin");
    write("sysvar1: %d",sysGetVariableInt(sysvar::Mynamespace::LockSign));
    status = 1;
    idx=0x741;
    setTimer(time1,2);
}


on timer time1
{
  write("trigger time");
  if(sysGetVariableInt(sysvar::Mynamespace::LockSign)==0)
  {
    sysSetVariableInt(sysvar::Mynamespace::LockSign,1);
  }
  status=0;
}

on message *
{
    if(this.byte(1)==0x51 & this.byte(2))
    {
      write("found: 0x%x",this.id);
      sysSetVariableInt(sysvar::Mynamespace::LockSign,0);
      cancelTimer(time1);
    }
}

on start
{
    msg.dlc = 3;
    msg.byte(0) = 2;
    msg.byte(1) = 0x11;
    msg.byte(2) = 0x1;
    write("begin while\n");
    while(status==1)
    {
        if(sysGetVariableInt(sysvar::Mynamespace::LockSign)==0)
        {
          write("send %d meg\n",idx);
          msg.id=idx;
          output(msg);
          idx++;
          sysSetVariableInt(sysvar::Mynamespace::LockSign,1);
          setTimer(time1,2);
        }
        else{
          write("LockSign\n");
        }
        
        if(idx==0x744)
        {
          status=0;
        }
      write("test");
    }  
}

我尝试将 while 代码放入“on key”中,但仍然不起作用

do-while capl canoe
1个回答
0
投票

CANoe 的工作模式可以描述为“协作多任务”。只有一个“线程”在运行,它执行整个模拟。 例如,当收到消息时,将执行所有关联的事件处理程序,例如

on message ...

。 当执行这些处理程序时,模拟会被阻止。

在您的情况下,

on start

中的代码永远不会完成,这将导致模拟停止。

您必须将代码和逻辑分成由事件触发的更小的部分。这些作品必须尽快完成。

我没有完全了解您的用例,但是您当前在

on start

中的代码可以简单地放入计时器中

variables
{
...
msTimer time2;
}

on timer time2
{
  msg.dlc = 3;
  msg.byte(0) = 2;
  msg.byte(1) = 0x11;
  msg.byte(2) = 0x1;
  if(sysGetVariableInt(sysvar::Mynamespace::LockSign)==0)
  {
    write("send %d meg\n",idx);
    msg.id=idx;
    output(msg);
    idx++;
    sysSetVariableInt(sysvar::Mynamespace::LockSign,1);
    setTimer(time1,2);
  }
  else{
    write("LockSign\n");
  }
        
  if(idx==0x744)
  {
    status=0;
  }
  setTimer(time2,10);
}

之前 while 循环中的内容现在将每 10 毫秒执行一次。

最有可能的代码可以通过使用

on sysvar Mynamespace::LockSign

进一步优化,仅在 sysvar 更改时做出反应而不是轮询。但这取决于您的要求。

    

© www.soinside.com 2019 - 2024. All rights reserved.