High-Precision Cyclic Broadcast & Timeout Supervision
ESC systems require rock-solid timing consistency. Yaw rate and lateral acceleration messages must be broadcast every 20ms ± 1ms. If an ECU fails to receive a required companion message within a defined timeout window (e.g. 100ms), a communication fault code (DTC) is flagged.
Timers in CAPL Scripting
In CAPL (CAN Application Programming Language), timers are a crucial feature for controlling time-based events and actions in embedded systems, particularly in automotive communication and testing. CAPL timers allow you to execute certain code after a defined delay, which is essential for tasks like periodic checks, timeouts, or deferred actions. Timers in CAPL can be set, started, stopped, and cleared, and they operate independently of the main program flow.
Key Features of Timers in CAPL
Timer Functions: CAPL provides several built-in functions to control and interact with timers.
Timer Events: Timer events trigger when a timer expires, and the corresponding event handler can execute a block of code.
Timer Functions in CAPL
SetTimer(): Starts or resets a timer.
CancelTimer(): Stops a running timer.
GetTimer(): Retrieves the current time remaining on a timer.
Timer Event Handler: The block of code executed when the timer expires.
Timer Types in CAPL
One-shot Timers: A timer that runs only once and expires after the set time.
Cyclic Timers: A timer that restarts automatically when it expires, providing periodic execution.
SetTimer()
The SetTimer() function starts a timer with a specified delay.
SetTimer(TimerName, DelayTime);
TimerName: The name of the timer (this must be declared).
DelayTime: The time in milliseconds after which the timer will expire.
CancelTimer()
The CancelTimer() function stops a running timer.
CancelTimer(TimerName);
TimerName: The name of the timer to cancel.
Timer Event Handler
When a timer expires, the associated event handler (a function) is executed. This function is defined like any other CAPL function but is triggered automatically when the timer times out.
on timer TimerName
{
// Actions to perform when the timer expires
}
Example 1: One-shot Timer
In this example, we set a one-shot timer to perform an action after 500 milliseconds.
// Declare the timer
variables
{
msTimer myTimer; // Timer to be used
}
// Event handler for CAN message
on message CAN_Message
{
// Start a timer for 500ms when CAN_Message is received
SetTimer(myTimer, 500);
}
// Event handler for the timer expiration
on timer myTimer
{
output("Timer expired after 500ms");
// Additional actions after timer expiration
}
Example 2: Cyclic Timer
A cyclic timer will repeat an action every 1000 milliseconds.
// Declare the timer
variables
{
msTimer cyclicTimer; // Cyclic timer
}
// Event handler to set the timer
on start
{
SetTimer(cyclicTimer, 1000); // Start the cyclic timer for 1 second
}
// Event handler for the timer expiration
on timer cyclicTimer
{
output("Cyclic Timer expired");
SetTimer(cyclicTimer, 1000); // Restart the timer for the next cycle
}
In this example, the cyclic timer runs every second and triggers the expiration event handler, which restarts the timer to repeat the cycle.
Example 3: Cancelling a Timer
If a timer needs to be stopped before it expires, the CancelTimer() function is used.
// Declare the timer
variables
{
msTimer timerToCancel; // Timer that will be cancelled
}
// Event handler to start the timer
on start
{
SetTimer(timerToCancel, 1000); // Start timer for 1 second
}
// Event handler to cancel the timer
on key 'C' // User presses the 'C' key to cancel the timer
{
CancelTimer(timerToCancel); // Cancel the timer
output("Timer cancelled by user.");
}
// Event handler for timer expiration (will not be triggered if the timer is cancelled)
on timer timerToCancel
{
output("This will not be printed, because the timer was cancelled.");
}
Example 4: Using GetTimer()
The GetTimer() function retrieves the remaining time for a running timer, which can be useful for debugging or controlling time-dependent processes.
// Declare the timer
variables
{
msTimer myTimer; // Timer to be used
}
// Event handler to set the timer
on start
{
SetTimer(myTimer, 2000); // Start the timer for 2 seconds
}
// Event handler to check the timer remaining time
on key 'T' // User presses 'T' to check remaining time
{
int remainingTime = GetTimer(myTimer); // Get the remaining time for the timer
output("Remaining time on myTimer: %d ms", remainingTime);
}
// Event handler for timer expiration
on timer myTimer
{
output("Timer expired!");
}
Timers and Timeouts
Timers are especially useful for handling timeouts. For example, a communication protocol might require a response within a certain time. If the response is not received within the timeout period, an error or retry action can be triggered.
// Declare the timer
variables
{
msTimer responseTimer; // Timer for response timeout
}
// Event handler to send a message
on message RequestMessage
{
SetTimer(responseTimer, 1000); // Wait for 1 second for response
}
// Event handler to handle the timeout
on timer responseTimer
{
output("Timeout! No response received.");
// Handle timeout (e.g., retry or report error)
}
Conclusion
Timers in CAPL are essential for handling timed actions, periodic tasks, and timeouts. By using functions like SetTimer(), CancelTimer(), and GetTimer(), along with timer event handlers, CAPL allows for precise control over time-based operations, which is particularly useful in CAN bus communication, testing, and embedded systems development.
- In CAPL, timers are one-shot by default! To make a timer cyclic, you MUST call `setTimer()` again inside its `on timer` event handler.
- Calling `setTimer()` on an already running timer overwrites the expiration deadline without error, resetting the countdown.
Select your answer for each question below to receive immediate correctness evaluation and in-depth technical rationale.
Create an ECU watchdog node. Set a 100ms timeout timer `tWatchdog`. Whenever message 0x100 is received, cancel and reset the timer back to 100ms. If `tWatchdog` ever expires, log a 'CRITICAL: ECU Heartbeat Lost!' warning to the Write window.
Verified CAPL implementation:
variables {
msTimer tWatchdog;
}
on start {
// Start initial watchdog window
setTimer(tWatchdog, 100);
}
on message 0x100 {
// Reset watchdog on frame arrival
cancelTimer(tWatchdog);
setTimer(tWatchdog, 100);
}
on timer tWatchdog {
writeLineEx(0, 3, "CRITICAL FAULT: Heartbeat message 0x100 timed out (>100ms)!");
// Set diagnostic fault flag
$ECU_CommFaultStatus = 1;
}