Код CAPL, задержка в коде

У меня есть тестовый код CAPL, который контролирует начало отправки сигнала CAN. Моя цель - отложить начало процесса отправки. Моя идея сделать это с помощью функции setTimer() в сочетании с isTimerActive().

В целом мой код выглядит следующим образом:

main() {   
CANstart();
function_2();
function_3();   
}

CANstart() {    
  SetTimer(Delay, 5000); //Timer initialization, set to be 5000ms

  while (isTimerActive()==1) {
    // this while loop avoids that the code is proceding while the settimer exception is being called and executed
  }

  StartCANTransmitting(); // After this function, jump back to main and proceed with function_2   
}

on timer Delay {
  // Do nothing, just wait   
}

Приведенный выше программный код приводит к зависанию в этом месте, CANoe не отвечает, и единственный способ завершить симуляцию - через диспетчер задач.

  • Дальнейшее изучение с моей стороны привело к выводу, что таймеру нужно больше времени для обработки и он вообще не выполняется.
  • Без функции isTimerActive () программный код не ожидает завершения таймера, и задержки вообще нет. Похоже, что код проходит без ожидания исключения.
  • Похоже, что CAPL очень плохо обрабатывает циклы.

Я проверяю stack overflow и следующие посты на форуме говорят об очень похожих проблемах, которые у меня есть, не предлагая никаких рабочих решений:

CAPL Программирование использования таймера в качестве задержки

Таймеры работают, а петли активны?

Функция задержки в CAPL, кроме testwaitfortimeout()

3 ответа

Похоже, у вас проблема с while (isTimerActive()==1) { заявление.

CAPL функция int isTimerActive требует параметров timer или mstimer переменная и возвращаемые значения 1, если таймер активен, иначе 0.

Вы можете проверить, активен ли таймер и время истекло, следующим образом.

timer t;
write("Active? %d", isTimerActive(t)); // writes 0
setTimer(t, 5);
write("Active? %d", isTimerActive(t)); // writes 1
write("Time to elapse: %d",timeToElapse(t)); // Writes 5

попробуйте добавить параметр timer в while (isTimerActive(Delay)==1) {

Я бы не предлагал использовать оператор while, вместо этого вы можете использовать таймер напрямую для вызова функции StartCANTransmitting() и ваш Main() должно быть MainTest()

void MainTest()
{
   TestModuleTitle("Sample Tests");
   TestModuleDescription("This test module calls some test cases to demonstrate ");
   CANstart();
   if (TestGetVerdictLastTestCase() == 1)
      Write("CANstart failed.");
   else
      Write("CANstart passed.");
}

testcase CANstart() {   
  // add info block to test case in report  
  TestReportAddMiscInfoBlock("Used Test Parameters");
  TestReportAddMiscInfo("Max. voltage", "19.5 V");
  TestReportAddMiscInfo("Max. current", "560 mA");
  TestReportAddMiscInfo("StartCANTransmitting");

  SetTimer(Delay, 5000); //Timer initialization, set to be 5000ms
}

on timer Delay {
  StartCANTransmitting();   
}

Я вижу много проблем с вашим кодом. На самом деле это совсем не похоже на код, но больше похоже на псевдокод. Компилируется ли он в вашем браузере CAPL?

main() {   
CANstart();
function_2();
function_3();   
}

Если это объявление функции, то в нем отсутствует как тип, так и возвращаемое значение. Кроме того, когда вы ожидаете main() быть выполненным?

То же самое относится к:

CANstart()

Давайте сделаем шаг назад. Вам нужно отложить начало передачи. Если вам нужно сделать это из-за того, что у вас работает код вне CANalyzer/CANoe, то я предлагаю вам вызвать приложение из командной строки (дополнительную информацию см. В руководстве).

Однако если вам нужно, чтобы в вашей конфигурации были запущены блоки, такие как блок воспроизведения, блок логина или что-то еще, я предлагаю вам сделать следующее:

variables {
    /* define your variables here. You need to define all messages you want to send and respective signal values if not defaulted */
    message 0x12345678 msg1;   // refer to CAPL guide on how to define message type variables
    msTimer delay;
    msTimer msgClock1;
}

on start {
    /* when you hit the start measurements button (default F9) */
    setTimer(delay, 5000);   // also note your syntax is wrong in the example
}

on timer delay {
    /* when timer expires, start sending messages */
    output(msg1);    // send your message
    setTimer(msgClock1,250);    // set timer for cyclic message sending
}

on timer msgClock1 {
    /* this mimicks the behaviour of a IG block */
    setTimer(msgClock1,250);    // keep sending message
    output(msg1)
}

Достигает ли это вашей цели? Пожалуйста, не стесняйтесь спрашивать более подробную информацию.

В тестовых модулях у вас есть множество функций ожидания. Вы можете отложить выполнение следующим образом:

      main() {   
  CANstart();
  testWaitForSysVar(sysvar::namespace::any, 5000);  // wait 5000ms or until @namespace::any is changed
  function_2();
  function_3();   
}

Пустой цикл while, как вы пробовали, потребляет все получаемые ресурсы и делает CANoe непригодным для использования.

Это решение не работает в узлах моделирования. Там вам нужно использовать код, основанный на событиях.

Другие вопросы по тегам