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
'''
}
}
}
}