Advertisement
Responsive Ad Slot (Vector Toolchains & Embedded Certifications)
๐Ÿš— Automotive System Focus: Body Control Module (BCM)

Global State Machines in the Variables Block

The BCM tracks state transitions across vehicle subsystemsโ€”such as Central Locking, Interior Ambient Lighting, and Hazard Flashers. State variables must persist between event triggers, which means they must be defined in the global `variables { }` section rather than local event handlers.

Variables in CAPL Scripting

CAPL (CAN Application Programming Language) is a programming language used for writing scripts in CANoe and CANalyzer, tools developed by Vector for simulating, testing, and analyzing network communication on CAN networks. CAPL allows users to write scripts to interact with CAN, LIN, and other network protocols, making it an essential tool for automotive engineers working with embedded systems.

What Are Variables in CAPL?

A variable in CAPL is a named storage location that holds a data value. This value can change during the execution of the program. Variables are used to store information such as sensor values, states of a device, timestamps, etc.

Types of Variables in CAPL

Basic Data Types: CAPL supports several primitive data types which are essential for declaring variables:

int: Integer (whole number).

float: Floating-point number.

bool: Boolean value (TRUE or FALSE).

char: Single character.

string: Array of characters (string of text).

long: A larger integer type.

unsigned: Positive-only integer type.

double: Double precision floating-point number.

Special Data Types

enum: A user-defined type with a set of named integer values.

struct: A user-defined composite data type that groups different variables together.

To declare a variable, you use the following syntax

CAPL CAPL - To declare a variable, you use the following syntax
data_type variable_name;

Where data_type is the type of data the variable will store, and variable_name is the name you assign to it.

Example

CAPL CAPL - Example
int counter;       // Declares an integer variable called 'counter'
float temperature; // Declares a floating-point variable called 'temperature'

Variable Initialization

You can also initialize a variable with a value at the time of declaration:

CAPL CAPL - Variable Initialization
int counter = 0;            // Integer variable initialized to 0
float temperature = 25.5;   // Float variable initialized to 25.5

To assign a value to a variable after its declaration

CAPL CAPL - To assign a value to a variable after its declaration
counter = 10;           // Assigns the value 10 to 'counter'
temperature = 30.2;     // Assigns the value 30.2 to 'temperature'

Variable Scope

CAPL CAPL - Variable Scope
Global variables: These are declared outside of any function, making them accessible throughout the script.
Example:
capl

int globalVar;   // Global variable
Local variables: These are declared inside functions and can only be used within the scope of that function.
Example:
capl

void myFunction() {
int localVar = 5;  // Local variable inside 'myFunction'
}

Example with Different Types of Variables

CAPL CAPL - Example with Different Types of Variables
// Declaring and initializing variables
int messageCounter = 0;          // Integer variable
float voltageLevel = 3.3;        // Float variable
bool isEngineRunning = true;     // Boolean variable
char deviceStatus = 'A';         // Char variable
string carModel = "Tesla";       // String variable
// Using variables in a function
void onCanMessageReceived() {
messageCounter++;            // Incrementing counter when a CAN message is received
if (isEngineRunning) {       // Checking if engine is running
voltageLevel = 12.0;     // Adjusting voltage level when engine is on
}
}
// Function to print device status
void printDeviceStatus() {
output("Device Status: %c", deviceStatus);   // Printing char variable
output("Car Model: %s", carModel);            // Printing string variable
}

Enumerations (enum)

Enumerations in CAPL are used to define a type with a set of predefined constants. This is useful for representing state machines, modes, or predefined sets of values.

CAPL CAPL - Enumerations (enum)
enum EngineState {
OFF,
IDLE,
RUNNING
};
EngineState currentEngineState = OFF;  // Declare an enum variable

Structures (struct)

Structures are used to define custom data types that can hold different types of data together. Each member of a structure can have a different type.

CAPL CAPL - Structures (struct)
struct VehicleStatus {
bool engineStatus;  // Engine running or not
int speed;          // Vehicle speed in km/h
float fuelLevel;    // Fuel level in percentage
};
VehicleStatus myCarStatus;  // Declare a variable of type VehicleStatus
void updateVehicleStatus() {
myCarStatus.engineStatus = true;  // Engine is running
myCarStatus.speed = 80;           // Speed is 80 km/h
myCarStatus.fuelLevel = 45.5;     // Fuel level is 45.5%
}

Variables in CAN Signal Communication

Variables can be linked to CAN signals or message signals. You can assign values to CAN signals, and their values can be monitored or modified.

CAPL CAPL - Variables in CAN Signal Communication
variables
{
message MyMessage;  // Declare a CAN message variable
}
on message MyMessage
{
// Accessing signals in the message
int speed = MyMessage.SignalSpeed;  // Retrieve the speed from the CAN message
output("Speed: %d km/h", speed);
}

Useful Built-In Variables and Functions

CAPL provides some built-in functions and variables that make handling data easier, such as the ability to get timestamps, access message data, and more:

GetTime(): Returns the current simulation time.

getSignalValue(): Used to read the value of a signal from a CAN message.

setSignalValue(): Used to write a value to a CAN signal.

CAPL CAPL - Useful Built-In Variables and Functions
variables
{
message MyMessage;
}
on message MyMessage
{
int signalValue = getSignalValue(MyMessage.SignalSpeed); // Get signal value
output("Received Speed: %d km/h", signalValue);
// Modify the signal value
setSignalValue(MyMessage.SignalSpeed, 100);
}

Conclusion

In CAPL, variables are a fundamental concept for storing and manipulating data during the execution of scripts. They allow you to track the state of your system, handle CAN messages, and implement complex logic for testing and simulation. Understanding variable types, scope, and how to use them with CAN signals is key to writing effective CAPL scripts.

โš ๏ธ Common Pitfalls & CANoe Troubleshooting Tips
  • Local variables inside event handlers (e.g. `on message`) lose their value once the handler returns. Never store cumulative counters or state machine states in local variables.
  • Variable initialization in the `variables { }` block executes when the measurement starts. Dynamic initializations depending on bus values should be handled in `on start`.
๐Ÿ“ Concept Mastery Assessment
12 Questions Score: 0 / 0

Select your answer for each question below to receive immediate correctness evaluation and in-depth technical rationale.

Question 1 of 12
Where must global variables and message objects be declared in a CAPL program file?
Explanation
All global variables, message buffers, timers, and structs in CAPL must be placed in the top-level 'variables { ... }' block.
Question 2 of 12
What is the lifetime of a variable declared locally inside a CAPL event handler (e.g. on message)?
Explanation
Local variables declared inside an event handler have automatic lifetime, existing only for the duration of that specific event execution.
Question 3 of 12
Can you use the 'static' keyword on local variables inside a CAPL event handler to retain value across events?
Explanation
CAPL does not support local 'static' variables within handlers. Any state that needs to persist across events must be declared in the global 'variables' block.
Question 4 of 12
What is an Environment Variable in CANoe / CAPL?
Explanation
Environment variables (prefixed with 'putValue' / 'getValue' or 'envVarName') bridge CANoe interactive panels and CAPL nodes.
Question 5 of 12
What are System Variables in CANoe (prefixed with '@')?
Explanation
System variables provide high-performance, structured simulation and panel data channels, referenced in CAPL via the '@namespace::variable' syntax.
Question 6 of 12
What syntax is used to write a value to a system variable in CAPL?
Explanation
System variables can be assigned directly using '@Namespace::VariableName = value;' or read as expressions.
Question 7 of 12
What is the scope of a variable declared inside the 'variables' block of a CAPL node?
Explanation
Variables in the 'variables' block have node-wide global scope within that specific simulation node.
Question 8 of 12
What happens if a local variable inside an event handler shares the same identifier as a global variable?
Explanation
CAPL follows standard block scoping: a local variable declaration shadows any global variable of the same name within that scope.
Question 9 of 12
Which built-in function outputs diagnostic and debug messages to the CANoe Write Window?
Explanation
'write()' and 'writeLineEx()' output formatted strings to the CANoe system Write Window.
Question 10 of 12
Can global variables in one CAPL node directly read local variables inside another CAPL node without communication buses?
Explanation
Simulation nodes model discrete electronic control units. They do not share memory directly, communicating via bus traffic or system variables.
Question 11 of 12
What is the naming convention restriction for variables in CAPL?
Explanation
Like C, CAPL identifiers must begin with a letter or underscore and cannot match keywords or event names.
Question 12 of 12
What happens to global variable values when simulation measurement is stopped and restarted in CANoe?
Explanation
Every measurement start (on start) resets the CAPL virtual machine, zero-initializing and evaluating initializers in the 'variables' section.
0 / 0 (0%)
Great job! Review the questions above and proceed when ready.
๐Ÿ› ๏ธ Hands-on Automotive Challenge: Vehicle Ignition State Machine Declaration

Declare an enumeration 'enum eVehiclePowerMode { POWER_OFF = 0, POWER_ACCESSORY = 1, POWER_ON = 2, POWER_START = 3 }' and a global state variable. Write an event handler for key press 'p' that cycles through the power modes sequentially and logs the transition.

Verified CAPL implementation:

CAPL Solution - Vehicle Ignition State Machine Declaration
variables {
  enum eVehiclePowerMode {
    POWER_OFF = 0,
    POWER_ACCESSORY = 1,
    POWER_ON = 2,
    POWER_START = 3
  };
  enum eVehiclePowerMode gCurrentPowerMode = POWER_OFF;
}

on key 'p' {
  // Cycle to next mode
  if (gCurrentPowerMode == POWER_START)
    gCurrentPowerMode = POWER_OFF;
  else
    gCurrentPowerMode = (enum eVehiclePowerMode)(gCurrentPowerMode + 1);

  write("Vehicle Power Mode transitioned to: %d", gCurrentPowerMode);
}
Advertisement
Responsive Ad Slot (Automotive Embedded Systems Career Resources)