Skip to main content

Interrupt Events

In eTrice the protocol etrice.api.interrupt.PInterrupt models an interrupt event. The protocol consists of two messages fire and event, which have higher priority than other eTrice messages. The flow of an interrupt event is as follows. First, the interrupt handler must create the eTrice message PInterrupt.fire. As soon as the execution returns to the eTrice thread, the eTrice runtime dispatches the PInterrupt.event message immediately before any other queued message. As a result, the interrupt event message will be received by the target state machine at once. The execution is always on the eTrice thread to avoid any concurrency issues from the interrupt context.

The following examples shows how to connect an interrupt handler to the eTrice application. First there is the simple actor AExternalUSBIsr, which exports the PInterrupt conjugated port to an external function called USB_register_port.

import etrice.api.interrupt.PInterrupt

ActorClass AExternalUSBIsr {
Interface {
conjugated Port isrUSBExported: PInterrupt
}
Structure {
external Port isrUSBExported
}
Behavior {
StateMachine {
State state
Transition init: initial -> state {
action '''
// export port isrUSBExported to external function
USB_register_port(isrUSBExported.export());
'''
}
}
}
}

The function USB_register_port saves the port handle to usbIsr_port. The interrupt handler can use this handle to trigger the fire message from its interrupt context.

// #include "etrice/api/interrupt/PInterrupt.h"

static PInterruptConjPort *usbIsr_port = NULL;

// called from eTrice initial transition
void USB_register_port(PInterruptConjPort *port) {
usbIsr_port = port;
}

// !! interrupt context !!
void MY_USB_INTERRUPT_HANDLER() {
if(usbIsr_port) {
PInterruptConjPort_fire(usbIsr_port);
}
}

The event is handled in actor AUSBService, which contains the previous actor AExternalUSBIsr. The port usbIsr is bound to AExternalUSBIsr.externalUsbIsr. If the interrupt handler triggers the fire message, the state machine will finally receive the associated event message on port usbIsr.

ActorClass AUSBService {
Structure {
Port usbIsr: PInterrupt
ActorRef externalUsbIsr: AExternalUSBIsr
Binding usbIsr and externalUsbIsr.isrUSBExported
}
Behavior {
StateMachine {
State state
Transition init: initial -> state
Transition receiveUSB: state -> state {
triggers {
<event: usbIsr>
}
action '''
// do something, e.g. read usb buffer
'''
}
}
}
}