The 7 CAPL Events you should know about

21 Feb 2018

CAPL - Communication Access Protocol Language is used by Vector tools like CANoe and CANalyzer. It is an event based language, that can be used for automating/semi-automating in a CAN environment. Its mostly like C with few changes. Global variables can be declared in variables{} section, with functions and events following. I'll cover the 6 events/functions unique to CAPL.

  • on start()
  • When you click the Measurement start - lightning icon to start your simulation in CANoe(or CANalyzer), the part of code here gets executed. Example:

    			
    
    		on start()
    		{
    				write("This will be printed on start-up!");
    		}
    		
    		

  • on pre-start()
  • This function will execute before start() event. This is useful for initting variables, setting delays etc. setStartdelay is a function unique to pre-start - that can be used to test timing parameters.

    				
    
    		on pre-start()
    		{
    			write("this will be executed before start()!");
    		}
    		
    		

  • on stop()
  • This event takes place on clicking the stop button in CANoe/CANalyzer window.
    Example:

    				
    
    			on stop(){
    				write("You clicked the red stop button!");
    			}
    				
    				

  • on key 'key-name'()
  • When key specified in 'key-name' is pressed, this event is triggered.

    				
    
    			on key 'a'
    			{
    				write("When a is pressed, this happens");
    			}
    			
    			

  • on envvar "Envvar name"()
  • CANoe has objects called environment variables, which interact with the user. These environment variables must be created and defined in Database files associated with the simulation (".dbc" files). When the associated Env-var changes, this event is called. Example :

    				
    
    			on envvar env_abc{
    				write("Value of env_abc is %d",getvalue(this));
    			}
    			
    			
    getvalue and putvalue are special functions, to get/put value of an environment value.
    "this" pointer refers to current env_var here

  • on message messagename()
  • This happens when the CAN message specified in messagename is received. messagename can be declared in variables{} portion and used here or else hex address can be given.
    Example:
    			
    
    		on message 0x100{
    			int data=0;
    			data=0x100.byte(0);
    			write("Data in 0x100 first byte, %d",data);
    		}
    		
    		
    			
    
    		variables{
    			message 0x100 messagename;
    		}
    
    		on message messagename()
    		{
    			write("Data in first byte, %d",messagename.byte(0));
    		}<
    
    		
    		
  • on timer()
  • Timers are special variables that trigger with a settimer() call and can be stopped with a canceltimer() call.
    They are useful to run parallel tasks and sequentials tasks also and play a big role in automation.
    Timers must be declared in variables{} section. There are two types of timers - mstimer and timer variables. Mstimer on setting, take values in Milliseconds and on timer event executes on completion of that value.
    For Timer variable, on timer event takes place after the seconds specified in settimer call is lapsed.
    Example:

    				
    			variables{
    				timer t1;
    				mstimer t2;
    				int t1delay=1;
    				int t2delay=1000;
    			}
    
    			on start(){
    				settimer(t1,t1delay);
    				settimer(t2,t2delay);
    			}
    
    			on timer t1{
    				write("One second has elapsed.");
    				settimer(t1,t1delay);
    			}
    
    			on timer t2{
    				write("1000 Milliseconds have elapsed.");
    				settimer(t2,t2delay);
    			}
    
    			on key 'a'{
    				canceltimer(t1);
    				canceltimer(t2);
    			}
    			
    			

    I'll end this article with an example of how to send a CAN message periodically :)
    	
    
    variables{
    	mstimer messagetimer;
    	int message_cycle_time = 100;
    	int count=0;
    	message CANdb::Messagename MessageA;
    }
    
    on key 'a'{
    	settimer(messagetimer,message_cycle_time);
    }
    
    on timer messagetimer()
    {
    	settimer(messagetimer,message_cycle_time);
    	count+=1;
    	if(count%2==0)
    		MessageA.byte(0)=0x00;
    	else
    		MessageA.byte(0)=0x01;
    	output(MessageA);
    }
    
    on key 'b'{
    	canceltimer(messagetimer);
    }
    
    
    Note that im setting timer at start of timer again. It will enter the timer again when 100 milliseconds have elapsed only. Any minute delays during processing can be avoided this way. Timer call happens only after current timer elapses. And inside I'm change byte(0) alternately to 0 or 1 based on count is even or odd. "output" sends the CAN message through the bus.