Communicate via LIN 
Motivation
LIN is commonly used as an inexpensive and decently reliable way for peripherals to communicate and can in some cases
be required to communicate with a device under test. The miniHIL is also capable of simulating LIN masters and slaves
and communicating over a CAN bus. For more information on how to set this up, read the
LIN bus adapter guide.
In this tutorial we will set up a LIN master, slave and scheduler to send messages from the slave to the master
without using the CAN bus, then output the data that the master receives.
Pre-requisites
On the miniHIL, the pins PD0(RX) and PD1(TX) are used by the LIN adapter. In our case, since we aren’t using
the bus, we simply connect the two pins together.
To prepare the SW create a new project as described in the "Creating a new project" How-To.
Finally, to be able to see some output, make sure you can log as described in here. Note that in this case you only need the USB connection. Log messages will be generated by the LIN tester below.
Instantiate the LIN in software
In this project, we will create three actors: The LIN master, LIN slave and a LIN tester that is used to select the
master’s schedule, start the master and slave and log data.
As a container we will use the Application contained in MiniHILApplication.room. So open the file in your newly
created project and go to the Structure Section of the Application actor.
There, create instances of the LIN actors as shown below.
RoomModel MiniHilProject {
//...
import etrice.api.interrupt.PInterrupt
import etrice.api.timer.PTimer
import etrice.api.logger.PLogger
import busadapters.api.lin.PLinPayload
import busadapters.api.lin.PLinCtrl
import busadapters.api.lin.PLinCtrlScheduler
import busadapters.platform.lin.ALinMasterController
import busadapters.platform.lin.ALinSlaveController
ActorClass Application {
Structure {
// ...
ActorRef slaveDevice: ALinSlaveDeviceController
ActorRef masterDevice: ALinDeviceMasterController
ActorRef linTester: ALinTester
}
}
![]() |
Imports for logging, timing and interrupts. |
![]() |
Imports the required ports. |
![]() |
Import the abstractions for master and slave. |
![]() |
Instantiate the actors. |
We will need to implement ALinSlaveDeviceController and ALinDeviceMasterController and currently these instantiations
will show errors.
In the following sections, we will implement and define the different actors behavior. Since the LIN hardware is abstracted by
further actors, we will only have to define frame tables and a schedule for the master in order for the nodes
to communicate. The only state needed to define our master and slave’s behavior is an initialization state.
If you are interested in details set the cursor on ALinMasterController and press F3.
Implementing the LIN master
For the master to communicate with its slaves, it will need a frame table, indicating which IDs it stores and whether
it wants to send or receive the corresponding data, and a scheduler table showing when the data should be transfered.
In our example, we will use the following code. We can see that a frame table is defined, as well as multiple schedules.
This example will only execute LIN_SchedulerTableEntries_DefaultTable, however for future projects it can be useful to
know how to define further schedules to, for example, share the diagnostic frames with ID 60 and 61.
Scheduler tables are defined by first creating a list of scheduler entries and then storing them in a LIN_SchedulerTable type
along with the number of entries.
We can also see that a ALinMasterController actor is defined inside of the master. This acts as our abstraction of the LIN hardware.
ActorClass ALinDeviceMasterController {
Interface {
Port payload: PLinPayload
Port ctrl: PLinCtrl
Port ctrlScheduler[5]: PLinCtrlScheduler
}
Structure {
usercode3 '''
#include "busadapters/platform/lin/LinImpl.h"
/* LIN Node Frame Table
{ id, length, store/send, data}*/
static const LIN_FrameTableEntry LIN_FrameTable_Controller[5] = {
{1, 3, own, {0xAA,0x55,23,0,0,0,0,0,0}}, // own = store data
{2, 8, ofInterest, {0,0,0,0,0,0,0,0,0}}, // ofInterest = send data
{3, 8, ofInterest, {0,0xFF,0,0,0,0,0,0,0}},
{60, 8, own, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
{61, 8, ofInterest, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}
};
/* LIN Node Scheduler Table(s) */
/* LIN_SchedulerEntry
* @param type: unconditional or sporadic, see wikipedia for info on frame types
* @param fid: number to identify frame
* @param delay: how often to transmit/request frame
* @param typeSpecificData: void pointer for unconditional/sporadic data
*/
// table 1
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_DefaultTable[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 1, .delay = 100.0, .typeSpecificData = NULL},
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 2, .delay = 100.0, .typeSpecificData = NULL},
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 3, .delay = 100.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_DefaultTable = {
3, // table length
LIN_SchedulerTableEntries_DefaultTable
};
// table 2
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_ControllerFrameOnly[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 1, .delay = 100.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_ControllerFrameOnly = {
1,
LIN_SchedulerTableEntries_ControllerFrameOnly
};
// table 3
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_MasterReqTable[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 60, .delay = 20.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_MasterReqTable = {
1,
LIN_SchedulerTableEntries_MasterReqTable
};
// table 4
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_SlaveRespTable[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 61, .delay = 20.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_SlaveRespTable = {
1,
LIN_SchedulerTableEntries_SlaveRespTable
};
// table 5
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_DiagMasterSlaveTable[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 60, .delay = 20.0, .typeSpecificData = NULL},
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 61, .delay = 20.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_DiagMasterSlaveTable = {
2,
LIN_SchedulerTableEntries_DiagMasterSlaveTable
};
static const LIN_SchedulerTable * LIN_SchedulerTableList_Controller[] = {
&LIN_SchedulerTableNull,
&LIN_SchedulerTable_DefaultTable,
&LIN_SchedulerTable_ControllerFrameOnly,
&LIN_SchedulerTable_MasterReqTable,
&LIN_SchedulerTable_SlaveRespTable,
&LIN_SchedulerTable_DiagMasterSlaveTable
};
'''
conjugated Port rxInterrupt: PInterrupt
ActorRef controller: ALinMasterController
Binding rxInterrupt and controller.rxDataIsr
Binding controller.payload and payload
Binding controller.ctrl and ctrl
Binding controller.ctrlScheduler and ctrlScheduler
}
Behavior {
StateMachine {
State Operational
Transition init: initial -> Operational {
action '''
// initialize LIN master
LIN_InitData initData = {
.baudRateBps = 19200
};
LIN_init(&initData);
LIN_configureSchedulerTableList(LIN_SchedulerTableList_Controller, 0);
LIN_registerDataRxPort(rxInterrupt.export(), LIN_FrameTable_Controller, 5);
'''
}
}
}
}
![]() |
Add the required ports |
![]() |
Import definitions for frames, schedules and initialization functions. |
![]() |
Frames to be sent/received. |
![]() |
Scheduler table entries. |
![]() |
Scheduler table. |
![]() |
List of schedules to pass to master abstraction. |
![]() |
Instantiation of master abstraction and required port connections. |
![]() |
Initialization behavior. |
Implementing the LIN slave
Similar to the master, we will have to define the slave’s frame table and initialize the slave. For this, we use the following code:
ActorClass ALinSlaveDeviceController {
Interface {
Port payload: PLinPayload
Port ctrl: PLinCtrl
}
Structure {
usercode3 '''
#include "busadapters/platform/lin/LinImpl.h"
/* LIN Node Frame Table
{ id, length, store/send, data}*/
static const LIN_FrameTableEntry LIN_FrameTable_Device2[4] = {
{3, 8, own, {1,2,3,4,5,6,7,8,0}}, // own = store data
{1, 3, ofInterest, {0,0,0,0,0,0,0,0,0}}, // ofInterest = send data
{60, 8, ofInterest, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
{61, 8, own, {0x01,0x02,0x03,0xFF,0xFF,0xFF,0xFF,0xFF}}
};
'''
conjugated Port rxInterrupt: PInterrupt
ActorRef controller: ALinSlaveController
Binding rxInterrupt and controller.rxDataIsr
Binding controller.payload and payload
Binding controller.ctrl and ctrl
SAP timer: PTimer
}
Behavior {
StateMachine {
State Operational
Transition init: initial -> Operational {
// initialize LIN slave
action '''
LIN_InitData initData = {
.baudRateBps = 19200
};
LIN_init(&initData);
LIN_registerDataRxPort(rxInterrupt.export(), LIN_FrameTable_Device2, 4);
'''
}
}
}
}
![]() |
Add the required ports |
![]() |
Import definitions for frames, schedules and initialization functions. |
![]() |
Frames to be sent/received. |
![]() |
Instantiation of slave abstraction and required port connections. |
![]() |
Initialization behavior. |
Implementing the LIN tester
We now add the code for the LIN tester. This involves connecting the tester to both master and slave, starting the
master and slave while also selecting the master’s schedule, and updating the slave’s data. This is all controlled
using the ports. The master’s schedulerCtrl is used to select the schedule to use, the masterCtrl and slaveCtrl
ports start the nodes and the payload ports can be used to update and read data.
In our example, we will update the slave’s data in frame 3 with an incrementing counter and then run
the master’s default schedule once per second. When a frame entry in the table is updated, the data
is automatically sent through the payload port. We will also add a state that reacts to this change
and logs the data.
Enumeration ELinScheduleTableSimpleDevice of uint8 {
Null = 0,
DefaultTable = 1,
ControllerFrameOnly = 2,
MasterReqTable = 3,
SlaveRespTable = 4,
DiagMasterSlaveTable = 5
}
ActorClass ALinTester {
Interface {
conjugated Port masterPayload: PLinPayload
conjugated Port masterCtrl: PLinCtrl
conjugated Port slaveCtrl: PLinCtrl
conjugated Port schedulerCtrl: PLinCtrlScheduler
conjugated Port slavePayload: PLinPayload
}
Structure {
usercode3 '''
#include "ELinScheduleTableSimpleDevice.h"
'''
external Port masterPayload
external Port masterCtrl
external Port slaveCtrl
external Port schedulerCtrl
external Port slavePayload
SAP timer: PTimer
SAP timerUpate: PTimer
SAP logger: PLogger
Attribute counter: uint8 = "0"
}
Behavior {
StateMachine {
State configuring
State setupScheduler
Transition init0: initial -> configuring {
action '''
timer.startTimeout(1000);
'''
}
Transition tr0: configuring -> setupScheduler {
triggers {
<timeout: timer>
}
// configure master and slave and start communication
action '''
masterCtrl.start();
slaveCtrl.start();
schedulerCtrl.break();
schedulerCtrl.notifyRolloverScheduleDone(false);
DLinScheduleState defaultSchedule = {ELinScheduleTableSimpleDevice_DefaultTable, 1};
schedulerCtrl.schedule(&defaultSchedule); // select master schedule
timer.startTimeout(1000);
'''
}
State scheduleDone
Transition tr1: setupScheduler -> scheduleDone {
triggers {
<scheduleDone: schedulerCtrl>
}
action '''timer.startTimeout(1000);'''
}
Transition tr2: scheduleDone -> scheduleDone {
triggers {
<scheduleDone: schedulerCtrl>
}
action '''timer.startTimeout(1000);'''
}
Transition tr3: scheduleDone -> scheduleDone {
// periodically set slave data
triggers {
<timeout: timer>
}
action '''
DLinPayload slaveData;
slaveData.fid = 0x03;
slaveData.data[0] = counter;
slaveData.data[1] = counter;
slaveData.data[2] = counter;
slaveData.data[3] = counter;
slaveData.data[4] = counter;
slaveData.data[5] = counter;
slaveData.data[6] = counter;
slaveData.data[7] = counter;
counter++;
slavePayload.setData(&slaveData); // set slave data
schedulerCtrl.runOnce(); // run schedule once'''
}
Transition log: scheduleDone -> scheduleDone {
// master automatically sends data over payload, we capture this and process it
triggers {
<data: masterPayload>
}
action '''
logger.logF("(Master) fid: %x, data: %x, %x, %x, %x, %x, %x, %x", transitionData->fid, transitionData->data[0], transitionData->data[1], transitionData->data[2], transitionData->data[3], transitionData->data[4], transitionData->data[5], transitionData->data[6]);
logger.log("------------------------");
'''
}
}
}
}
![]() |
Ports for communicating with master and slave. |
![]() |
Instantiate ports, timer, logger and counter. |
![]() |
Select schedule and start master and slave. |
![]() |
update slave data and run schedule once. |
![]() |
Log updated data. |
Connect the tester to the nodes
Finally before being able to run the code, we need to update our MiniHilProject.room application to connect the test
to the nodes.
RoomModel MiniHilProject {
ActorClass Application {
Structure {
// ...
ActorRef slaveDevice: ALinSlaveDeviceController
ActorRef masterDevice: ALinDeviceMasterController
ActorRef linTester: ALinTester
Binding linTester.masterCtrl and masterDevice.ctrl
Binding linTester.masterPayload and masterDevice.payload
Binding linTester.schedulerCtrl and masterDevice.ctrlScheduler
Binding linTester.slaveCtrl and slaveDevice.ctrl
Binding linTester.slavePayload and slaveDevice.payload
}
}
![]() |
Bindings between tester and nodes. |
Running the example
Once you have flashed and started the target you should see output like this in your terminal.
(Master) fid: 3, data: 0, 0, 0, 0, 0, 0, 0 ------------------------ (Master) fid: 3, data: 1, 1, 1, 1, 1, 1, 1 ------------------------ (Master) fid: 3, data: 2, 2, 2, 2, 2, 2, 2 ------------------------ (Master) fid: 3, data: 3, 3, 3, 3, 3, 3, 3 ------------------------
Summary
-
Instantiate LIN master and slave
-
Create schedules and frame tables
-
Set and read master and slave’s data
See Also
Complete example file
RoomModel MiniHilProject {
import etrice.api.timer.PTimer
import etrice.api.logger.PLogger
import etrice.api.interrupt.PInterrupt
// LIN imports
import busadapters.api.lin.PLinPayload
import busadapters.api.lin.PLinCtrl
import busadapters.api.lin.PLinCtrlScheduler
import busadapters.platform.lin.ALinMasterController
import busadapters.platform.lin.ALinSlaveController
/**
* The "root" of every miniHIL test project is the Application actor which should be defined in the MiniHilProject.room file (This file, the ActorClass below).
* This actor commonly contains the (one and only) test actor (of the system), the simulation elements and any other actors which are used in conjunction with the test cases.
* Usually this actor also contains all or most of the Actors which provide the hardware abstraction (e.g. UART, DigitalIN/OUT, AnalogIn/OUT, etc.).
*/
ActorClass Application {
Structure {
// LIN main and test actors
ActorRef slaveDevice: ALinSlaveDeviceController
ActorRef masterDevice: ALinDeviceMasterController
ActorRef linTester: ALinTester
Binding linTester.masterCtrl and masterDevice.ctrl
Binding linTester.masterPayload and masterDevice.payload
Binding linTester.schedulerCtrl and masterDevice.ctrlScheduler
Binding linTester.slaveCtrl and slaveDevice.ctrl
Binding linTester.slavePayload and slaveDevice.payload
}
}
Enumeration ELinScheduleTableSimpleDevice of uint8 {
Null = 0,
DefaultTable = 1,
ControllerFrameOnly = 2,
MasterReqTable = 3,
SlaveRespTable = 4,
DiagMasterSlaveTable = 5
}
ActorClass ALinTester {
Interface {
conjugated Port masterPayload: PLinPayload
conjugated Port masterCtrl: PLinCtrl
conjugated Port slaveCtrl: PLinCtrl
conjugated Port schedulerCtrl: PLinCtrlScheduler
conjugated Port slavePayload: PLinPayload
}
Structure {
usercode3 '''
#include "ELinScheduleTableSimpleDevice.h"
'''
external Port masterPayload
external Port masterCtrl
external Port slaveCtrl
external Port schedulerCtrl
external Port slavePayload
SAP timer: PTimer
SAP timerUpate: PTimer
SAP logger: PLogger
Attribute counter: uint8 = "0"
}
Behavior {
StateMachine {
State configuring
State setupScheduler
Transition init0: initial -> configuring {
action '''
timer.startTimeout(1000);
'''
}
Transition tr0: configuring -> setupScheduler {
triggers {
<timeout: timer>
}
// configure master and slave and start communication
action '''
masterCtrl.start();
slaveCtrl.start();
schedulerCtrl.break();
schedulerCtrl.notifyRolloverScheduleDone(false);
DLinScheduleState defaultSchedule = {ELinScheduleTableSimpleDevice_DefaultTable, 1};
schedulerCtrl.schedule(&defaultSchedule); // select master schedule
timer.startTimeout(1000);
'''
}
State scheduleDone
Transition tr1: setupScheduler -> scheduleDone {
triggers {
<scheduleDone: schedulerCtrl>
}
action '''timer.startTimeout(1000);'''
}
Transition tr2: scheduleDone -> scheduleDone {
triggers {
<scheduleDone: schedulerCtrl>
}
action '''timer.startTimeout(1000);'''
}
Transition tr3: scheduleDone -> scheduleDone {
// periodically set slave data
triggers {
<timeout: timer>
}
action '''
DLinPayload slaveData;
slaveData.fid = 0x03;
slaveData.data[0] = counter;
slaveData.data[1] = counter;
slaveData.data[2] = counter;
slaveData.data[3] = counter;
slaveData.data[4] = counter;
slaveData.data[5] = counter;
slaveData.data[6] = counter;
slaveData.data[7] = counter;
counter++;
slavePayload.setData(&slaveData); // set slave data
schedulerCtrl.runOnce(); // run schedule once'''
}
Transition log: scheduleDone -> scheduleDone {
// master automatically sends data over payload, we capture this and process it
triggers {
<data: masterPayload>
}
action '''
logger.logF("(Master) fid: %x, data: %x, %x, %x, %x, %x, %x, %x", transitionData->fid, transitionData->data[0], transitionData->data[1], transitionData->data[2], transitionData->data[3], transitionData->data[4], transitionData->data[5], transitionData->data[6]);
logger.log("------------------------");
'''
}
}
}
}
ActorClass ALinSlaveDeviceController {
Interface {
Port payload: PLinPayload
Port ctrl: PLinCtrl
}
Structure {
usercode3 '''
#include "busadapters/platform/lin/LinImpl.h"
/* LIN Node Frame Table
{ id, length, store/send, data}*/
static const LIN_FrameTableEntry LIN_FrameTable_Device2[4] = {
{3, 8, own, {1,2,3,4,5,6,7,8,0}}, // own = store data
{1, 3, ofInterest, {0,0,0,0,0,0,0,0,0}}, // ofInterest = send data
{60, 8, ofInterest, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
{61, 8, own, {0x01,0x02,0x03,0xFF,0xFF,0xFF,0xFF,0xFF}}
};
'''
conjugated Port rxInterrupt: PInterrupt
ActorRef controller: ALinSlaveController
Binding rxInterrupt and controller.rxDataIsr
Binding controller.payload and payload
Binding controller.ctrl and ctrl
SAP timer: PTimer
}
Behavior {
StateMachine {
State Operational
Transition init: initial -> Operational {
// initialize LIN slave
action '''
LIN_InitData initData = {
.baudRateBps = 19200
};
LIN_init(&initData);
LIN_registerDataRxPort(rxInterrupt.export(), LIN_FrameTable_Device2, 4);
'''
}
}
}
}
ActorClass ALinDeviceMasterController {
Interface {
Port payload: PLinPayload
Port ctrl: PLinCtrl
Port ctrlScheduler[5]: PLinCtrlScheduler
}
Structure {
usercode3 '''
#include "busadapters/platform/lin/LinImpl.h"
/* LIN Node Frame Table
{ id, length, store/send, data}*/
static const LIN_FrameTableEntry LIN_FrameTable_Controller[5] = {
{1, 3, own, {0xAA,0x55,23,0,0,0,0,0,0}}, // own = store data
{2, 8, ofInterest, {0,0,0,0,0,0,0,0,0}}, // ofInterest = send data
{3, 8, ofInterest, {0,0xFF,0,0,0,0,0,0,0}},
{60, 8, own, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
{61, 8, ofInterest, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}
};
/* LIN Node Scheduler Table(s) */
/* LIN_SchedulerEntry
* @param type: unconditional or sporadic, see wikipedia for info on frame types
* @param fid: number to identify frame
* @param delay: how often to transmit/request frame
* @param typeSpecificData: void pointer for unconditional/sporadic data
*/
// table 1
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_DefaultTable[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 1, .delay = 100.0, .typeSpecificData = NULL},
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 2, .delay = 100.0, .typeSpecificData = NULL},
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 3, .delay = 100.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_DefaultTable = {
3, // table length
LIN_SchedulerTableEntries_DefaultTable
};
// table 2
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_ControllerFrameOnly[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 1, .delay = 100.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_ControllerFrameOnly = {
1,
LIN_SchedulerTableEntries_ControllerFrameOnly
};
// table 3
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_MasterReqTable[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 60, .delay = 20.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_MasterReqTable = {
1,
LIN_SchedulerTableEntries_MasterReqTable
};
// table 4
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_SlaveRespTable[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 61, .delay = 20.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_SlaveRespTable = {
1,
LIN_SchedulerTableEntries_SlaveRespTable
};
// table 5
static const LIN_SchedulerEntry LIN_SchedulerTableEntries_DiagMasterSlaveTable[] = {
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 60, .delay = 20.0, .typeSpecificData = NULL},
{.type = LIN_ScheduleEntryType_UNCONDITIONAL, .fid = 61, .delay = 20.0, .typeSpecificData = NULL}
};
static const LIN_SchedulerTable LIN_SchedulerTable_DiagMasterSlaveTable = {
2,
LIN_SchedulerTableEntries_DiagMasterSlaveTable
};
static const LIN_SchedulerTable * LIN_SchedulerTableList_Controller[] = {
&LIN_SchedulerTableNull,
&LIN_SchedulerTable_DefaultTable,
&LIN_SchedulerTable_ControllerFrameOnly,
&LIN_SchedulerTable_MasterReqTable,
&LIN_SchedulerTable_SlaveRespTable,
&LIN_SchedulerTable_DiagMasterSlaveTable
};
'''
conjugated Port rxInterrupt: PInterrupt
ActorRef controller: ALinMasterController
Binding rxInterrupt and controller.rxDataIsr
Binding controller.payload and payload
Binding controller.ctrl and ctrl
Binding controller.ctrlScheduler and ctrlScheduler
}
Behavior {
StateMachine {
State Operational
Transition init: initial -> Operational {
// initialize LIN master
action '''
LIN_InitData initData = {
.baudRateBps = 19200
};
LIN_init(&initData);
LIN_configureSchedulerTableList(LIN_SchedulerTableList_Controller, 0);
LIN_registerDataRxPort(rxInterrupt.export(), LIN_FrameTable_Controller, 5);
'''
}
}
}
}
}