6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
AutomotiveGeeks
Your car might be smarter than you
CAPL Scripting
Rohan Chandrakar February 9, 2021 Uncategorized
Stands for Communication Access Programming Language.
CAPL is a C based programming language which allows you to control the
application in CANoe.
CANoe is the comprehensive software tool for development, test and analysis of
individual ECUs and entire ECU networks. This tool helps to develop code that
makes CANoe simulation more smart and powerful.
For example, you can send a message on the bus in response to a key press (on
key), track the occurrence of messages on the bus (on message), or execute certain
actions cyclically (on timer).
Introduction to CAPL
CAPL programs have three distinct parts.
1. Global Variable Declarations
2. Event Procedures
3. User-Defined Functions
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 1/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
1 Variables{
2 //Message Declaration
3 message 0x121 Msg = { // Declare message with Id 0x121
4 dlc = 3, // Set Data Length Code = 1
5 byte(0) = 1 // Set 1st data byte
6 byte(1) = 0x12
7 <SignalName> = 2;// Assign value to any signal
8
9 //timer declaration
10 timer msgTimer1 // Timer variable in seconds
11 msTimer msgTimer2; // Timer variable in miliseconds
12
13 // General data types
14 Char Name[20] = "Rohan"
15 int count = 4;
16 Double length = 21.4;
17 dword = 0x123243
18 byte dtcID[3] = {'0x94', '0x21', '0x22'}
19 }
The types of events that can be detected in CAPL include –
the pressing of the start
stop button
user keyboard entry
CAN message reception
the timeout of a timer
user input via a graphic panel (available only in CANoe).
CAPL Examples:
CAPL is mostly used for two types of tasks.
1. ECU Simulation: Using network nodes in CANoe.
2. Test case scripting: Using available test modules
(CAPL / XML).
Usage of Network Node:
Different type of events:
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 2/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
1 Variables{
2 Message 0x123 msg;
3 mstimer msg_Timer;
4 int count = 0;
5 }
6 on key 'a' // Key press event
7 {
8 setTimer(msg_Timer , 100);
9 }
10 on timer msg_Timer //timer event
11 {
12 Write("Timer <msg_timer> has expired");
13 }
14 on message 0x123 //message event
15 {
16 Write("corresponding message is received over bus");
17 }
18 on Signal <signal name> // signal event
19 {
20 write("Corresponding signal has been received over bus")
21 }
Send periodic frame
1 Variables
2 {
3 Message 0x123 msg;
4 mstimer msg_Timer;
5 }
6 on key 'a'
7 {
8 settimer(msg_Timer, 100);
9 }
10 on timer msg_Timer
11 {
12 msg.dlc = 0x08;
13 msg.byte(0) = 0x02;
14 output(msg);
15 settimer(msg_Timer, 100);
16 }
17 on key 's'
18 {
19 cancelTimer(msg_Timer);
20 }
Listening to a message/Signal
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 3/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
1 Variables{
2 Message 0x123 msg;
3 mstimer msg_Timer;
4 int count = 0;
5 }
6 on key 'a'
7 {
8 setTimer(msg_Timer , 100);
9 }
10 on timer msg_Timer
11 {
12 msg.dlc = 0x08;
13 msg.byte(0) = 0x02;
14 output(msg);
15 setTimer(msg_Timer, 100);
16 }
17 on message 0x123
18 {
19 if(this.byte(0) == 0x02)
20 write("count = %d", count++);
21 }
22 on Signal <signal name>
23 {
24 write("Signal value = %d", @this);
25 }
Send Diagnostics request using CAPL test module
1 Variables
2 {
3 diagRequest OEM.Default_Session_Start defaultReq;
4 }
5 MainTest()
6 {
7 TC1();
8 }
9
10 Testcase TC1()
11 {
12 diagSendRequest(defaultReq);
13 testwaitfordiagResponse(defaultReq, 500);
14 if(diaggetLastResponse(defaultReq) == -1)
15 teststepPass("Positive Response Received");
16 else
17 teststepfail("Negative Response received");
18 }
Usage of user defined functions
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 4/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
1 Testcase TC1()
2 {
3 ChangeOperationCycle(100);
4 }
5
6 ChangeOperationCycle(int count)
7 {
8 int ignCycle = 0;
9 Teststep("","Changing Ignition Cycle %d timers", count);
10
11 for(; , count > 0 ; count--)
12 {
13 TestStep("","Ignition cycle change iteration = %d" ,
14 putValue(Envnetwork_mode_h3 , 0); // Putti
15 testwaitfortimeour(20000);
16
17 TestStep("Waking up the network");
18 putValue(Envnetwork_mode_h3 , 2); // Wakin
19 testwaitfortimeour(5000);
20 }
Analysing and comparing diagnostics response
diagGetRespParameter function extracts a certain data (parameter from CDD)
from the diagnostic response data and allows us to compare the it with the
expected result. Based on that judgement can be provided.
1 Testcase TC1() //Example 1
2 {
3 diagRequest OEM.Read_DID_Supplier_Software_Number req_DI
4
5 diagSendRequest(req_DID_0xF194);
6 testwaitfordiagResponse(defaultReq, 500);
7 diagGetRespParameter(req_DID_0xF194,"Supplier_ECU_Softwa
8
9 if(strncmp(readSWVersion,releaseSWVersion, strlen(releas
10 teststepFail("","Current Software Version is not as
11 else
12 teststepPass("","Current Software Version is as exp
13 }
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 5/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
1 Testcase TC2()
2 {
3 //Variable
4 diagRequest OEM.Evaporator_Sensor_Voltage_Raw_0xB01A_Rea
5 diagResponse OEM.Evaporator_Sensor_Voltage_Raw_0xB01A_Re
6
7 double output[1];
8 int ret;
9
10 //Teststeps
11 diagSendRequest(req_EvapTempVoltage);
12 testwaitfordiagResponse(req_EvapTempVoltage, 500);
13 diagGetLastResponse(req_EvapTempVoltage, res_EvapTempVol
14 diagGetParameter (res_EvapTempVoltage,"Evaporator_Sensor
15
16 if ( output[0] < 1.2 && output[0] > 0.8 )
17 testStepPass("Evaporator raw voltage read through DI
18 else
19 testStepFail("Evaporator Raw Voltage read through DI
20 }
User defined function for send/receive diagnostics request
Following is a user defined function which can be used for sending a diagnostics
request and provide a judgement based on the response.
1 Testcase TC1()
2 {
3 diagRequest OEM.Default_Session_Start defaultReq;
4 diagResponse OEM.Default_Session_Start defaultRes;
5 int posResponse = 0;
6 int negResponse = 1;
7 int expectedNRC = 0;
8
9 SendAndReceive_DiagReq(defaultReq, defaultRes,"Request for D
10 }
11 // Parameter 1: Diagnostic Request object extracted from CDD
12 // Parameter 2: Diagnostic Response object, in order to catc
13 // Parameter 3: Character array to define the request being
14 // Parameter 4: Type of response expected. 0 for Positive an
15 // Parameter 5: If negative response is expected(i.e type of
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 6/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
1 SendAndReceive_DiagReq(diagRequest *req, diagResponse *res,
2 {
3 TestStep("Send Diagnostic Request ",description);
4 Switch(typeOfResponse)
5 {
6 case 0 : if (0>req.SendRequest())
7 {
8 testStepFail("Error when trying to send (t
9 }
10 else
11 {
12 testReportWriteDiagObject(req);
13 testStepPass("SendRequest successful!");
14 }
15
16 switch (testWaitForDiagResponse(req, 2000))
17 {
18 //Timeout
19 case 0: teststepfail("No reply from EC
20 break;
21
22 case 1: if (diaggetLastResponseCode(re
23 {
24 diagGetLastResponse(req, res
25 testReportWriteDiagObject(re
26 teststepPass("Positive Respo
27 }
28 else
29 {
30 diagGetLastResponse(req, res
31 testReportWriteDiagObject(re
32 teststepfail("","Negative re
33 }
34 break;
35 }
36 break;
37
38 case 1 : if (0>req.SendRequest())
39 {
40 testStepFail("Error when trying to send (t
41 }
42 else
43 {
44 testReportWriteDiagObject(req);
45 testStepPass("SendRequest successful!");
46 }
47
48 switch (testWaitForDiagResponse(req, 2000))
49 {
50 //Timeout
51 case 0: teststepfail("No reply from EC
52 break;
53
54 case 1: if (diaggetLastResponseCode(re
55 {
56 diagGetLastResponse(req, res
57 testReportWriteDiagObject(re
58 teststepFail("Positive Respo
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 7/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
59 }
60 else
61 {
62 if(diaggetLastResponseCode(r
63 {
64 teststeppass("","Expected
65 }
66 else
67 {
68 teststepfail("","Wrong Neg
69 }
70 }
71 break;
72 }
73 break;
74 }
75 }
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 8/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
1 endRawDiagReq(Message *req ,diagResponse *res,char descripti
2 {
3 TestStep("Send Diagnostic Request %s",description);
4
5 SetDataIntoMessageFrame(req,data);
6
7
8 Switch(typeOfResponse)
9 {
10 case 0 : output(req);
11 switch (testWaitForDiagResponse(2000))
12 {
13 //Timeout
14 case 0: teststepfail("No reply from EC
15 break;
16
17 case 1: if (diaggetLastResponseCode()
18 {
19 diagGetLastResponse(res);
20 testReportWriteDiagObject(re
21 teststepPass("Positive Respo
22 }
23 else
24 {
25 diagGetLastResponse(res);
26 testReportWriteDiagObject(re
27 teststepfail("","Negative re
28 }
29 break;
30 }
31 break;
32
33
34 case 1 : output(req);
35 switch (testWaitForDiagResponse(2000))
36 {
37 //Timeout
38 case 0: teststepfail("No reply from EC
39 break;
40
41 case 1: if (diaggetLastResponseCode()
42 {
43 diagGetLastResponse(res);
44 testReportWriteDiagObject(re
45 teststepFail("Positive Respo
46 }
47 else
48 {
49 if(diaggetLastResponseCode()
50 {
51 teststeppass("","Expected
52 }
53 else
54 {
55 teststepfail("","Wrong Neg
56 }
57 }
58 break;
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 9/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
59 }
60 break;
61
62 }
63 }
64
65 SetDataIntoMessageFrame(Message *req, byte data[])
66 {
67 int index=0;
68 for(index=0; index<=7; index++)
69 {
70 req.byte(index)= data[index];
71 }
72 req.dlc=0x08;
73 Testcasecomment("Message to send",req);
74 }
User defined function to fetch DTC status from memory
Below are the two functions which can be used to get the DTC data and provide the
judgement based on the expected result.
1 Testcase TC1()
2 {
3 diagRequest OEM.FaultMemory_Read req_readFaultMemory;
4 diagResponse OEM.FaultMemory_Read res_readFaultMemory;
5
6 dword dtcID = 0x932312;
7 dword activeStatus;
8
9 readFaultMemory(req_readFaultMemory, res_readFaultMemory
10
11 // Parameter 1: Diagnostic Request object extracted from CDD
12 // Parameter 2: Diagnostic Response object, in order to catc
13 // Parameter 3: DTC ID which needs to be validated
14 // Parameter 4: expected status of the DTC
15 }
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 10/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
1 dword readFaultMemory(diagRequest *req , diagResponse *res,
2 {
3 dword ret;
4
5 ret = GetDTCstatus(req, res, dtcToCheck);
6 write("%x", ret);
7 if(ret == expectedStatus)
8 TeststepPass("","Expected DTC: %x , is present in the me
9 else
10 Teststepfail("","Expected DTC: %x , is present in the me
11
12 return 0;
13 }
14
15 dword GetDTCstatus(diagRequest *req , diagResponse *res, dwo
16 {
17 dword DTC;
18 byte statusByte;
19 byte bit;
20 int i;
21 char textBuffer[200];
22 int count=0;
23 byte statusmask[1]= {0x09};
24
25 diagSetParameterRaw(req, "DTCStatusMask",statusmask, 1);
26
27 if (0>req.SendRequest()) // Start sending
28 {
29 testStepFail("Error when trying to send (the first frame
30 }
31 else
32 {
33 testReportWriteDiagObject(req);
34 testStepPass("SendRequest successful!");
35 }
36
37 switch (testWaitForDiagResponse(req, 2000)) // 2 sec timeout
38 {
39 case 0: // timeout
40 teststepfail("No reply from ECU");
41 break;
42
43 case 1: // response received
44 diagGetLastResponse(req, res);
45 //testReportWriteDiagObject(res);
46 if (diaggetLastResponseCode(req) == -1)
47 {
48 count = req.GetRespIterationCount( "ListOfDTC");
49 // write("count=%d", count);
50 for(i=0; i<count;i++)
51 {
52 DTC = req.GetComplexRespParameter("ListOfDTC",
53 if(DTC == dtcToCheck)
54 {
55 return req.GetComplexRespParameter("ListOfDT
56 }
57 }
58 }
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 11/12
6/26/25, 9:54 AM CAPL Scripting – AutomotiveGeeks
59 else
60 {
61 diagGetParameter(res, "RC", textBuffer, elCoun
62 write("Negative response received.\nNegative r
63 return 0;
64 }
65 break;
66 }
67 return 0;
68 }
Rohan Chandrakar February 9, 2021 Uncategorized
Leave a comment
AutomotiveGeeks, Create a free website or blog at WordPress.com.
https://automotivegeeks.wordpress.com/2021/02/09/capl-scripting/ 12/12