LIN Service API
Using the LIN Controller
The LIN Service API provides a LIN bus abstraction through the ILinController
interface.
A LIN controller is created by calling CreateLinController
given a controller and network name:
auto* linMasterController = participant->CreateLinController("LinMaster", "LIN1");
LIN controllers will only communicate within the same network.
Initialization
Before the LIN Controller can be used, it must be initialized. The initialization is performed by setting up a
LinControllerConfig
and passing it to Init()
. The LinControllerMode
must be set to either
LinControllerMode::Master
or LinControllerMode::Slave
and the baud rate must be specified. Further, the
LinControllerConfig
provides the configuration on which LIN IDs the controller will receive
(LinFrameResponseMode::Rx
) or respond to (LinFrameResponseMode::TxUnconditional
) frames.
The following example configures a LIN controller as a LIN slave with a baud rate of 20’000 baud. Furthermore, LIN ID 0x11 is configured for transmission:
LinFrameResponse response;
response.frame.id = 0x11;
response.frame.checksumModel = LinChecksumModel::Enhanced;
response.frame.dataLength = 8;
response.frame.data = {1, 2, 3, 4, 5, 6, 7, 8};
response.responseMode = LinFrameResponseMode::TxUnconditional;
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
slaveConfig.frameResponses.push_back(response);
linController->Init(slaveConfig);
Note that Init()
must only be called once. A second call of Init()
or operations on an uninitialized LIN node will
result in an exception. For the configuration, also keep in mind that the LIN protocol allows multiple nodes to be
configured for reception, but only one node to provide a response. This restriction is not evaluated upon Init()
,
but only during operation.
Extending the configuration during operation
Initialized LIN nodes can use SetFrameResponse()
to configure a response or reception during operation.
SetFrameResponse()
is useful for cases where a LIN slave is not aware of its full configuration upon initialization.
Reconfiguration of already used ID on the particular node are discarded. If used on a slave, the new configuration
will become active once the master receives the updated configuration.
For a LIN master, the AUTOSAR API SendFrame()
will also extend the configuration and can be used for IDs not explicitly
defined in Init()
. If used with LinFrameResponseType::MasterResponse
, the master will configure
LinFrameResponseMode::TxUnconditional
, if used with LinFrameResponseType::SlaveResponse
, the master will configure
LinFrameResponseMode::Rx
on the given ID. In case of LinFrameResponseType::SlaveToSlave
, no reconfiguration takes place,
but the master will receive a call to its FrameStatusHandler
with LinFrameStatus::LIN_TX_OK
, confirming the
initiation of the slave-to-slave communication.
Initiating LIN Transmissions
Data is transferred in the form of a LinFrame
, reception and acknowledgment is handled in the FrameStatusHandler
.
A LIN master can initiate the transmission of a frame using the AUTOSAR API SendFrame()
or the non-AUTOSAR API
SendFrameHeader()
. If a LIN slave provides the response, SendFrame()
requires that a corresponding frame
response was configured before at a LIN slave using Init()
or SetFrameResponse()
.
If using SendFrame()
with LinFrameResponseType::MasterResponse
, the response doesn’t have to be preconfigured and the
payload provided in the frame parameter of SendFrame()
will be used. If the LIN master uses the non-AUTOSAR API
SendFrameHeader()
, a LIN node has to be configured with LinFrameResponseMode::TxUnconditional
on that ID, possibly the master
itself.
In all cases except SendFrame()
with LinFrameResponseType::MasterResponse
, the responding node will receive the
header and complete the transmission using the payload of its current transmit buffer. The buffer can be updated
with UpdateTxBuffer()
on the node that is configured with LinFrameResponseMode::TxUnconditional
for the corresponding ID.
Sending Data
The transmission of a frame can be initiated using SendFrame()
or SendFrameHeader()
:
Using
SendFrame()
withLinFrameResponseType::MasterResponse
, the frame can be sent in one call and the master provides both header and response. ALinFrame
must be setup with the LIN ID, data, data length and the desired checksum model:// Prepare a frame with id 0x10 for transmission LinFrame masterFrame; masterFrame.id = 0x10; masterFrame.dataLength = 8; masterFrame.data = {'M', 'A', 'S', 'T', 'E', 'R', 0, 0}; masterFrame.checksumModel = LinChecksumModel::Enhanced; // initiate the frame transmission using the AUTOSAR interface master->SendFrame(masterFrame, LinFrameResponseType::MasterResponse);
When using
SendFrame()
withLinFrameResponseType::SlaveResponse
orLinFrameResponseType::SlaveToSlave
, a slave has to be preconfigured withLinFrameResponseMode::TxUnconditional
on that ID. With these response types, only the ID of theLinFrame
used inSendFrame()
is taken into account. The actual payload and frame settings are provided by the TX buffer of the responding slave. The following example assumes that a slave is configured as seen in Initialization:// The slave is configured to respond on ID 0x11 LinFrame slaveResponseFrame; slaveResponseFrame.id = 0x11; // initiate the frame transmission using the AUTOSAR interface master->SendFrame(slaveResponseFrame, LinFrameResponseType::SlaveResponse);
Using SendFrame()
with LinFrameResponseType::SlaveResponse
assumes that the master is interested in the response
and will configure itself for reception (LinFrameResponseMode::Rx
).
When using
SendFrameHeader()
, the transmission is initiated by sending the header. The node (either master or slave) configured withLinFrameResponseMode::TxUnconditional
will provide the response. The actual payload and frame settings are provided by the TX buffer of the responding LIN node. The following example also assumes that a slave is configured as seen in Initialization:// Slave: LinFrame updatedSlaveResponse; updatedSlaveResponse.id = 0x11; updatedSlaveResponse.dataLength = 8; updatedSlaveResponse.data = {'S', 'L', 'A', 'V', 'E', 1, 2, 3}; updatedSlaveResponse.checksumModel = LinChecksumModel::Enhanced; slave->UpdateTxBuffer(updatedSlaveResponse); // Master: // Transmit the frame header, the response will be provided by the slave. master->SendFrameHeader(0x11);
Transmission acknowledgment
To be notified for the success or failure of the transmission, a FrameStatusHandler
should be registered using
AddFrameStatusHandler()
:
// Register FrameStatusHandler to receive data from the LIN slave
auto frameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
master->AddFrameStatusHandler(frameStatusHandler);
A successful transmission is confirmed via the registered callback, for example:
frameStatusHandler(master, frameStatusEvent);
// With:
// frameStatusEvent.timestamp: timeEndOfFrame;
// frameStatusEvent.frame: masterFrame;
// frameStatusEvent.status: LinFrameStatus::LIN_TX_OK;
If multiple controllers have configured LinFrameResponseMode::TxUnconditional
on the same LIN ID, a collision occurs on the bus,
which is indicated by LinFrameStatus::LIN_TX_ERROR
.
Receiving data from a slave
Beside transmission acknowledgment, the FrameStatusHandler
is also used for reception. To receive data, the
FrameStatusHandler
must be registered using AddFrameStatusHandler()
, which is called by the LIN controller when
a frame is received and the LIN node is configured for reception with LinFrameResponseMode::Rx
on that LIN ID:
// Register FrameStatusHandler to receive data from the LIN slave
auto frameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
master->AddFrameStatusHandler(frameStatusHandler);
The incoming LinFrameStatusEvent
holds a LinFrameStatus
indicating the success (LinFrameStatus::LIN_RX_OK
) or
failure (LinFrameStatus::LIN_RX_ERROR
) of the transmission. If a LIN slave has previously setup a matching
LinFrameResponse
for transmission, the registered FrameStatusHandler
will deliver a LinFrameStatusEvent
as
follows:
frameStatusHandler(master, frameStatusEvent);
// With:
// frameStatusEvent.timestamp: timeEndOfFrame;
// frameStatusEvent.frame: slaveFrame;
// frameStatusEvent.status: LinFrameStatus::LIN_RX_OK;
If more than one slave provided a response, the master will receive a LinFrameStatus::LIN_RX_ERROR
, the slaves will
see LinFrameStatus::LIN_TX_ERROR
.
Data length and checksum model
A LinDataLength
and LinFrameStatus::LinChecksumModel
can be provided for a given ID when configuring a reception or initiating a transmission.
A frame will arrive with LinFrameStatus::LIN_RX_ERROR
if there is a mismatch between configured and received data length or checksum model.
However, a LIN node configured for reception might not know beforehand about the data length or checksum model provided in the response.
In this case, the reception can be configured with the wildcards LinDataLengthUnknown
(255) or LinFrameStatus::LinChecksumModel::Unknown
in the respective parameters of the LinFrame
.
If the wildcards are used, the validation of the incoming data length or checksum model are skipped.
The values provided by the sender are then used in the FrameStatusHandler
.
Managing the event handlers
Adding a handler will return a HandlerId
which can be used to remove the handler via:
API and Data Type Reference
LIN Controller API
-
class ILinController
The LIN controller can assume the role of a LIN master or a LIN slave. All LIN nodes must be configured with their respective role using ILinController::Init(LinControllerConfig) to perform data transmission and reception.
AUTOSAR-like LIN interface:
SendFrame() initiates a frame transfer for a given LinFrameResponseType. For LinFrameResponseType::MasterResponse, the controller doesn’t need to be configured for transmission on this LIN ID. Requires LinControllerMode::Master.
non-AUTOSAR LIN interface:
SendFrameHeader() initiates the transmission of a LIN frame for a particular LIN identifier. For a successful transmission, exactly one LIN slave or master must have previously set a corresponding frame response for unconditional transmission. Requires LinControllerMode::Master.
UpdateTxBuffer() updates the response data for a particular LIN identifier. Can be used with LinControllerMode::Master and LinControllerMode::Slave.
Public Types
-
using CallbackT = std::function<void(ILinController *controller, const MsgT &msg)>
Generic LIN callback method.
-
using FrameStatusHandler = CallbackT<LinFrameStatusEvent>
Callback type to indicate the end of a LIN LinFrame transmission. Cf., AddFrameStatusHandler(FrameStatusHandler);
-
using GoToSleepHandler = CallbackT<LinGoToSleepEvent>
Callback type to indicate that a go-to-sleep frame has been received. Cf., AddGoToSleepHandler(GoToSleepHandler);
-
using WakeupHandler = CallbackT<LinWakeupEvent>
Callback type to indicate that a wakeup pulse has been received. Cf., AddWakeupHandler(WakeupHandler);
Public Functions
-
virtual ~ILinController() = default
-
virtual void Init(LinControllerConfig config) = 0
Initialize the LIN controller defining its role and RX/TX configuration.
All controllers must be initialized exactly once to take part in LIN communication.
AUTOSAR Name: Lin_Init
- Parameters
config – The controller configuration contains:
controllerMode, either sets LIN master or LIN slave mode.
baudRate, determine transmission speeds (only used for detailed simulation).
frameResponses, a vector of LinFrameResponse. This must contain the final configuration on which LIN Ids the controller will receive (LinFrameResponseMode::Rx) or respond to (LinFrameResponseMode::TxUnconditional) frames. An exception is the use of SendFrame() for LinFrameResponseType::MasterResponse, which allows to extend the configuration during operation.
- Throws
SilKit::StateError – if the LIN Controller is configured with LinControllerMode::Inactive
SilKit::StateError – if Init() is called a second time on this LIN Controller.
SilKit::StateError – if InitDynamic() has already been called on the LIN Controller.
-
virtual auto Status() const noexcept -> LinControllerStatus = 0
Get the current status of the LIN Controller, i.e., Operational or Sleep.
-
virtual void SendFrame(LinFrame frame, LinFrameResponseType responseType) = 0
Initiate a LIN data transfer of a given LinFrameResponseType (AUTOSAR LIN master interface)
The responseType determines if frame.data is used for the frame response or if a different node has to provide it:
MasterResponse: SilKit::Services::Lin::LinFrame is sent from this controller to all connected slaves using frame.data. The LIN Master doesn’t have to be configured with LinFrameResponseMode::TxUnconditional on this LIN ID.
SlaveResponse: the frame response must be provided by a connected slave and is received by this controller.
SlaveToSlave: the frame response must be provided by a connected slave and is ignored by this controller.
AUTOSAR Name: Lin_SendFrame
- Parameters
frame – Provides the LIN identifier, checksum model, and optional data.
responseType – Determines which LIN Node will provide the frame response.
- Throws
SilKit::StateError – if the LIN Controller is not initialized or not a master node.
SilKit::StateError – if InitDynamic() has been called on the LIN Controller.
-
virtual void SendFrameHeader(LinId linId) = 0
Initiate a LIN data transfer by sending a LIN header (AUTOSAR LIN master interface)
- Parameters
linId – Provides the LIN header identifier. The node that is configured to respond on this ID will complete the transmission and provide the response data.
- Throws
SilKit::StateError – if the LIN Controller is not initialized or not a master node.
-
virtual void UpdateTxBuffer(LinFrame frame) = 0
Update the response data. The LIN controller needs to be configured with TxUnconditional on this ID.
- Parameters
frame – Provides the LIN ID and data used for the update.
- Throws
SilKit::StateError – if the LIN Controller is not initialized.
SilKit::ConfigurationError – if the LIN Controller is not configured with TxUnconditional on this ID.
SilKit::StateError – if InitDynamic() has been called on the LIN Controller.
-
virtual void SetFrameResponse(LinFrameResponse response) = 0
Set a RX/TX configuration during operation.
- Parameters
response – The frame and response mode to be configured.
- Throws
SilKit::StateError – if the LIN Controller is not initialized.
SilKit::StateError – if InitDynamic() has been called on the LIN Controller.
-
virtual void GoToSleep() = 0
Transmit a go-to-sleep-command and set ControllerState::Sleep and enable wake-up.
AUTOSAR Name: Lin_GoToSleep
- Throws
SilKit::StateError – if the LIN Controller is not initialized or not a master node.
-
virtual void GoToSleepInternal() = 0
Set ControllerState::Sleep without sending a go-to-sleep command.
AUTOSAR Name: Lin_GoToSleepInternal
- Throws
SilKit::StateError – if the LIN Controller is not initialized.
-
virtual void Wakeup() = 0
Generate a wake up pulse and set ControllerState::Operational.
AUTOSAR Name: Lin_Wakeup
- Throws
SilKit::StateError – if the LIN Controller is not initialized.
-
virtual void WakeupInternal() = 0
Set ControllerState::Operational without generating a wake up pulse.
AUTOSAR Name: Lin_WakeupInternal
- Throws
SilKit::StateError – if the LIN Controller is not initialized.
-
virtual auto AddFrameStatusHandler(FrameStatusHandler handler) -> HandlerId = 0
Reports the SilKit::Services::Lin::LinFrameStatus of a LIN SilKit::Services::Lin::LinFrame transmission and provides the transmitted frame.
The FrameStatusHandler is used for reception and acknowledgement of LIN frames. The direction (prefixed with LIN_TX_ or LIN_RX_) and error state of the tranmission is encoded in the SilKit::Services::Lin::LinFrameStatus.
- Returns
Returns a SilKit::Util::HandlerId that can be used to remove the callback.
-
virtual void RemoveFrameStatusHandler(HandlerId handlerId) = 0
Remove a FrameStatusHandler by SilKit::Util::HandlerId on this controller.
- Parameters
handlerId – Identifier of the callback to be removed. Obtained upon adding to respective handler.
-
virtual auto AddGoToSleepHandler(GoToSleepHandler handler) -> HandlerId = 0
The GoToSleepHandler is called whenever a go-to-sleep frame is received.
Note: The LIN controller does not automatically enter sleep mode on reception of a go-to-sleep frame. I.e., GoToSleepInternal() must be called manually.
Note: This handler will always be called, independently of the SilKit::Services::Lin::LinFrameResponseMode configuration for LIN ID 0x3C. However, regarding the FrameStatusHandler, the go-to-sleep frame is treated like every other frame, i.e. the FrameStatusHandler is only called for LIN ID 0x3C if configured as LinFrameResponseMode::Rx.
- Returns
Returns a SilKit::Util::HandlerId that can be used to remove the callback.
-
virtual void RemoveGoToSleepHandler(HandlerId handlerId) = 0
Remove a GoToSleepHandler by SilKit::Util::HandlerId on this controller.
- Parameters
handlerId – Identifier of the callback to be removed. Obtained upon adding to respective handler.
-
virtual auto AddWakeupHandler(WakeupHandler handler) -> HandlerId = 0
The WakeupHandler is called whenever a wake up pulse is received.
Note: The LIN controller does not automatically enter operational mode on wake up pulse detection. I.e., WakeInternal() must be called manually.
- Returns
Returns a SilKit::Util::HandlerId that can be used to remove the callback.
-
virtual void RemoveWakeupHandler(HandlerId handlerId) = 0
Remove a WakeupHandler by SilKit::Util::HandlerId on this controller.
- Parameters
handlerId – Identifier of the callback to be removed. Obtained upon adding to respective handler.
Data Structures
-
struct LinFrame
A LIN LinFrame.
This Type is used to provide LIN ID, checksum model, data length and data.
AUTOSAR Name: Lin_PduType
Public Members
-
LinChecksumModel checksumModel = {LinChecksumModel::Unknown}
Checksum Model.
-
LinDataLength dataLength = {0}
Data length.
-
std::array<uint8_t, 8> data = {}
The actual payload.
-
LinChecksumModel checksumModel = {LinChecksumModel::Unknown}
-
struct LinFrameResponse
Configuration data for a LIN Slave task for a particular LIN ID.
Public Members
-
LinFrame frame
frame must provide the LIN LinId for which the response is configured.
If responseMode is LinFrameResponseMode::TxUnconditional, the frame data is used for the transaction.
-
LinFrameResponseMode responseMode = {LinFrameResponseMode::Unused}
Determines if the LinFrameResponse is used for transmission (TxUnconditional), reception (Rx) or ignored (Unused).
-
LinFrame frame
-
struct LinControllerConfig
Configuration data to initialize the LIN Controller Cf.: ILinController::Init(LinControllerConfig config);
Public Members
-
LinControllerMode controllerMode = {LinControllerMode::Inactive}
Configure as LIN master or LIN slave.
-
LinBaudRate baudRate = {0}
The operational baud rate of the controller. Used in a detailed simulation.
-
std::vector<LinFrameResponse> frameResponses
Optional LinFrameResponse configuration.
FrameResponses can also be configured at a later point using ILinController::UpdateTxBuffer() and ILinController::SetFrameResponses().
-
LinControllerMode controllerMode = {LinControllerMode::Inactive}
-
struct LinFrameStatusEvent
A LIN frame status event delivered in the ILinController::FrameStatusHandler.
-
struct LinWakeupEvent
A LIN wakeup event delivered in the ILinController::WakeupHandler.
Public Members
-
std::chrono::nanoseconds timestamp
Time of the event.
-
TransmitDirection direction
The direction of the wakeup pulse.
-
std::chrono::nanoseconds timestamp
-
struct LinGoToSleepEvent
A LIN wakeup event delivered in the ILinController::GoToSleepHandler.
Public Members
-
std::chrono::nanoseconds timestamp
Time of the event.
-
std::chrono::nanoseconds timestamp
Enumerations and Typedefs
-
using SilKit::Services::Lin::LinId = SilKit_LinId
The identifier of a LIN LinFrame.
This type represents all valid identifier used by ILinController::SendFrame(), ILinController::SendFrameHeader().
Range: 0…0x3F
-
enum SilKit::Services::Lin::LinChecksumModel
The checksum model of a LIN SilKit::Services::Lin::LinFrame.
This type is used to specify the Checksum model to be used for the LIN LinFrame.
AUTOSAR Name: Lin_FrameCsModelType
Values:
-
enumerator Unknown
Unknown checksum model. If configured with this value, the checksum model of the first reception will be used.
-
enumerator Enhanced
Enhanced checksum model.
-
enumerator Classic
Classic checksum model.
-
enumerator Unknown
-
using SilKit::Services::Lin::LinDataLength = SilKit_LinDataLength
The data length of a LIN LinFrame in bytes.
This type is used to specify the number of data bytes to copy.
AUTOSAR Name: Lin_FrameDlType
Range: 0…8
-
const LinDataLength SilKit::Services::Lin::LinDataLengthUnknown = SilKit_LinDataLengthUnknown
If configured for reception with this value, the data length validation of incoming frames is skipped.
-
enum SilKit::Services::Lin::LinFrameResponseType
Controls the behavior of ILinController::SendFrame()
Determines whether the master also provides a frame response or if the frame response is expected to be provided from a slave.
AUTOSAR Name: Lin_FrameResponseType
Values:
-
enumerator MasterResponse
Response is generated from this master node.
-
enumerator SlaveResponse
Response is generated from a remote slave node.
-
enumerator SlaveToSlave
Response is generated from one slave to and received by another slave, for the master the response will be anonymous, it does not have to receive the response.
-
enumerator MasterResponse
-
enum SilKit::Services::Lin::LinFrameResponseMode
Controls the behavior of a LIN Slave task for a particular LIN ID.
Values:
-
enumerator Unused
The LinFrameResponse corresponding to the ID is neither received nor transmitted by the LIN slave.
-
enumerator Rx
The LinFrameResponse corresponding to the ID is received by the LIN slave.
-
enumerator TxUnconditional
The LinFrameResponse corresponding to the ID is transmitted unconditionally by the LIN slave.
-
enumerator Unused
-
enum SilKit::Services::Lin::LinFrameStatus
The state of a LIN transmission.
Used to indicate the success or failure of a LIN transmission to a registered ILinController::FrameStatusHandler.
Note: the enumeration values directly correspond to the AUTOSAR type Lin_StatusType. Not all values are used in the SIL Kit.
AUTOSAR Doc: LIN operation states for a LIN channel or frame, as returned by the API service Lin_GetStatus().
Values:
-
enumerator NOT_OK
(currently not in use)
AUROSAR Doc: Development or production error occurred
-
enumerator LIN_TX_OK
The controller successfully transmitted a frame response.
AUTOSAR Doc: Successful transmission.
-
enumerator LIN_TX_BUSY
(currently not in use)
AUTOSAR Doc: Ongoing transmission (Header or Response).
-
enumerator LIN_TX_HEADER_ERROR
(currently not in use)
AUTOSAR Doc: Erroneous header transmission such as: Mismatch between sent and read back data, Identifier parity error, or Physical bus error
-
enumerator LIN_TX_ERROR
(currently not in use)
AUTOSAR Doc: Erroneous response transmission such as: Mismatch between sent and read back data, Physical bus error
-
enumerator LIN_RX_OK
The controller received a correct frame response.
AUTOSAR Doc: Reception of correct response.
-
enumerator LIN_RX_BUSY
(currently not in use)
AUTOSAR Doc: Ongoing reception: at least one response byte has been received, but the checksum byte has not been received.
-
enumerator LIN_RX_ERROR
The reception of a response failed.
Indicates a mismatch in expected and received data length or a checksum error. Checksum errors occur when multiple slaves are configured to transmit the same frame or when the sender and receiver use different checksum models.
AUTOSAR Doc: Erroneous response reception such as: Framing error, Overrun error, Checksum error, or Short response
-
enumerator LIN_RX_NO_RESPONSE
No LIN controller did provide a response to the frame header.
AUTOSAR Doc: No response byte has been received so far.
-
enumerator NOT_OK
-
enum SilKit::Services::Lin::LinControllerMode
Used to configure a LIN controller as a master or slave.
Cf. LinControllerConfig, ILinController::Init()
Values:
-
enumerator Inactive
The LIN controller has not been configured yet and is inactive. This does not indicate sleep mode.
-
enumerator Master
A LIN controller with active master task and slave task.
-
enumerator Slave
A LIN controller with only a slave task.
-
enumerator Inactive
-
using SilKit::Services::Lin::LinBaudRate = SilKit_LinBaudRate
The operational baud rate of the controller.
Range: 200…20’000 Bd
-
enum SilKit::Services::Lin::LinControllerStatus
The operational state of the controller, i.e., operational or sleeping.
Values:
-
enumerator Unknown
The controller state is not yet known.
-
enumerator Operational
Normal operation.
-
enumerator Sleep
Sleep state operation; in this state wake-up detection from slave nodes.
-
enumerator SleepPending
Sleep pending state is reached when a GoToSleep is issued.
-
enumerator Unknown
Usage Examples
This section contains more complex examples that show the interaction of two or more LIN controllers. Although the LIN controllers would typically belong to different participants and reside in different processes, their interaction is shown here sequentially to demonstrate cause and effect.
Assumptions:
Variables
master
,slave
,slave1
, andslave2
are of typeILinController
.Variable
timeEndOfFrame
indicates the end of frame time stamp when using the detailed simulation. Otherwise, the value oftimeEndOfFrame
is undefined.UseAutosarInterface
is a boolean variable that indicates whether to use the AUTOSAR API or the non-AUTOSAR API. It will most likely not be used in practice, and only serves to show the various uses of the API.
Successful Transmission from Master to slave
This example shows a successful data transfer from a LIN master to a LIN slave. The transmission must be initiated by the master.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
// Slave Setup
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
// Setup LinFrameResponseMode::Rx for LIN ID 0x10 and 0x11 on the slave
LinFrame slaveFrame;
slaveFrame.id = 0x10;
slaveFrame.checksumModel = LinChecksumModel::Enhanced;
slaveFrame.dataLength = 8;
slaveFrame.data = {'S', 'L', 'A', 'V', 'E', 0, 0, 0};
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::Rx});
slaveFrame.id = 0x11;
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::Rx});
slave->Init(slaveConfig);
// Register FrameStatusHandler to receive data
auto slave_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
slave->AddFrameStatusHandler(slave_FrameStatusHandler);
// ------------------------------------------------------------
// Master Setup
LinControllerConfig masterConfig;
masterConfig.controllerMode = LinControllerMode::Master;
masterConfig.baudRate = 20000;
// Setup LinFrameResponseMode::TxUnconditional for LIN ID 0x11 on the master
LinFrame masterFrame;
masterFrame.id = 0x11;
masterFrame.dataLength = 8;
masterFrame.data = {'M', 'A', 'S', 'T', 'E', 'R', 0, 0};
masterFrame.checksumModel = LinChecksumModel::Enhanced;
masterConfig.frameResponses.push_back(LinFrameResponse{masterFrame, LinFrameResponseMode::TxUnconditional});
master->Init(masterConfig);
// Register FrameStatusHandler to receive confirmation of the successful transmission
auto master_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
master->AddFrameStatusHandler(master_FrameStatusHandler);
if (UseAutosarInterface)
{
// Transmit the frame 0x10 without configuration on master, slave has configured RX for 0x10.
LinFrame masterFrame;
masterFrame.id = 0x10;
masterFrame.checksumModel = LinChecksumModel::Enhanced;
masterFrame.dataLength = 8;
masterFrame.data = {'M', 'A', 'S', 'T', 'E', 'R', 0, 0};
// AUTOSAR API
master->SendFrame(masterFrame, LinFrameResponseType::MasterResponse);
}
else
{
// Alternative, non-AUTOSAR API
// Transmit the frame header, the master response is configured.
master->SendFrameHeader(0x11);
}
// In both cases (AUTOSAR and non-AUTOSAR), the following callbacks will be triggered:
// - TX confirmation for the master, who initiated the transmission
// and provided the frame response
master_FrameStatusHandler(master, LinFrameStatusEvent{ timeEndOfFrame, masterFrame, LinFrameStatus::LIN_TX_OK });
// - RX for the slave, who received the frame response
slave_FrameStatusHandler(slave, LinFrameStatusEvent{ timeEndOfFrame, masterFrame, LinFrameStatus::LIN_RX_OK });
Successful Transmission from slave to Master
This example shows a successful data transfer from a LIN slave to a LIN master. The transmission must be initiated by the master.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
// Slave Setup
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
// Setup LinFrameResponseMode::TxUnconditional for LIN ID 0x10 and 0x11 on the slave
LinFrame slaveFrame;
slaveFrame.id = 0x10;
slaveFrame.checksumModel = LinChecksumModel::Enhanced;
slaveFrame.dataLength = 8;
slaveFrame.data = {'S', 'L', 'A', 'V', 'E', 1, 0, 0};
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::TxUnconditional});
slaveFrame.id = 0x11;
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::TxUnconditional});
slave->Init(slaveConfig);
// Register FrameStatusHandler to receive an acknowledgement for
// the successful transmission
auto slave_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
slave->AddFrameStatusHandler(slave_FrameStatusHandler);
// ------------------------------------------------------------
// Master Setup
LinControllerConfig masterConfig;
masterConfig.controllerMode = LinControllerMode::Master;
masterConfig.baudRate = 20000;
// Setup LinFrameResponseMode::Rx for LIN ID 0x11 on the master
LinFrame masterFrame;
masterFrame.id = 0x11;
masterFrame.dataLength = 8;
masterFrame.checksumModel = LinChecksumModel::Enhanced;
masterConfig.frameResponses.push_back(LinFrameResponse{masterFrame, LinFrameResponseMode::Rx});
master->Init(masterConfig);
// Register FrameStatusHandler to receive data from the LIN slave
auto master_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
master->AddFrameStatusHandler(master_FrameStatusHandler);
// ------------------------------------------------------------
// Perform TX from slave to master, i.e., the slave provides the
// frame response, the master receives it.
if (UseAutosarInterface)
{
// AUTOSAR API
LinFrame frameRequest;
frameRequest.id = 0x10;
frameRequest.checksumModel = LinChecksumModel::Enhanced;
master->SendFrame(frameRequest, LinFrameResponseType::SlaveResponse);
}
else
{
// Alternative, non-AUTOSAR API
master->SendFrameHeader(0x11);
}
// In both cases (AUTOSAR and non-AUTOSAR), the following callbacks will be triggered:
// - RX for the master, who received the frame response
master_FrameStatusHandler(master, LinFrameStatusEvent{ timeEndOfFrame, slaveFrame, LinFrameStatus::LIN_RX_OK });
// - TX confirmation for the slave, who provided the frame response
slave_FrameStatusHandler(slave, LinFrameStatusEvent{ timeEndOfFrame, slaveFrame, LinFrameStatus::LIN_TX_OK });
Successful Transmission from slave to slave
This example shows how data is transferred from one LIN slave to another one. The data transfer must be initiated by a LIN master.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
// Slave 1 Setup (Sender)
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
// Setup LinFrameResponseMode::TxUnconditional for LIN ID 0x11 on slave1
LinFrame slaveFrame;
slaveFrame.id = 0x11;
slaveFrame.checksumModel = LinChecksumModel::Enhanced;
slaveFrame.dataLength = 8;
slaveFrame.data = {'S', 'L', 'A', 'V', 'E', 1, 0, 0};
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::TxUnconditional});
slave1->Init(slaveConfig);
// Register FrameStatusHandler to receive data
auto slave1_FrameStatusHandler = [](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {
};
slave1->AddFrameStatusHandler(slave1_FrameStatusHandler);
// ------------------------------------------------------------
// Slave 2 Setup (Receiver)
LinControllerConfig slave2Config;
slave2Config.controllerMode = LinControllerMode::Slave;
slave2Config.baudRate = 20000;
// Setup LinFrameResponseMode::Rx for LIN ID 0x11 on slave2
LinFrame slaveFrame;
slaveFrame.id = 0x11;
slaveFrame.checksumModel = LinChecksumModel::Enhanced;
slaveFrame.dataLength = 8;
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::Rx});
slave2->Init(slave2Config);
// Register FrameStatusHandler to receive data
auto slave2_FrameStatusHandler = [](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {
};
slave2->AddFrameStatusHandler(slave2_FrameStatusHandler);
// ------------------------------------------------------------
// Master Setup
LinControllerConfig masterConfig;
masterConfig.controllerMode = LinControllerMode::Master;
masterConfig.baudRate = 20000;
master->Init(masterConfig);
// Register FrameStatusHandler to receive confirmation of the successful transmission
auto master_FrameStatusHandler = [](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {
};
master->AddFrameStatusHandler(master_FrameStatusHandler);
// ------------------------------------------------------------
// Perform TX from slave to slave, i.e., slave1 provides the response, slave2 receives it.
if (UseAutosarInterface)
{
// AUTOSAR API
LinFrame frameRequest;
frameRequest.id = 0x11;
frameRequest.checksumModel = LinChecksumModel::Enhanced;
master->SendFrame(frameRequest, LinFrameResponseType::SlaveToSlave);
}
else
{
// Alternative, non-AUTOSAR API
master->SendFrameHeader(0x11);
}
// In both cases (AUTOSAR and non-AUTOSAR), the following callbacks will be triggered:
// - TX confirmation for slave1, who provided the frame response
slave1_FrameStatusHandler(slave1, LinFrameStatusEvent{timeEndOfFrame, slave1Frame, LinFrameStatus::LIN_TX_OK});
// - RX for slave2, who received the frame response
slave2_FrameStatusHandler(slave2, LinFrameStatusEvent{timeEndOfFrame, slave1Frame, LinFrameStatus::LIN_RX_OK});
Erroneous Transmission from Master to Slave - Multiple Responses
This example shows what happens when a master attempts to send a Frame while there is slave that has configured a TX response for the same LIN ID.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
// Slave Setup (Sender)
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
// Setup LinFrameResponseMode::TxUnconditional for LIN ID 0x10 and 0x11 on the slave
LinFrame slaveFrame;
slaveFrame.id = 0x10;
slaveFrame.checksumModel = LinChecksumModel::Enhanced;
slaveFrame.dataLength = 8;
slaveFrame.data = {'S', 'L', 'A', 'V', 'E', 0, 0, 0};
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::TxUnconditional});
slaveFrame.id = 0x11;
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::TxUnconditional});
slave->Init(slaveConfig);
// Register FrameStatusHandler to receive data
auto slave_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
slave->AddFrameStatusHandler(slave_FrameStatusHandler);
// ------------------------------------------------------------
// Master Setup
LinControllerConfig masterConfig;
masterConfig.controllerMode = LinControllerMode::Master;
masterConfig.baudRate = 20000;
// Also setup a TX Response for LIN ID 0x11 on the master (Errorneous Setup!)
LinFrame masterFrame;
masterFrame.id = 0x11;
masterFrame.dataLength = 8;
masterFrame.data = {'M', 'A', 'S', 'T', 'E', 'R', 0, 0};
masterFrame.checksumModel = LinChecksumModel::Enhanced;
masterConfig.frameResponses.push_back(LinFrameResponse{masterFrame, LinFrameResponseMode::TxUnconditional});
master->Init(masterConfig);
// Register FrameStatusHandler to receive confirmation of the successful transmission
auto master_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
master->AddFrameStatusHandler(master_FrameStatusHandler);
if (UseAutosarInterface)
{
// Transmit the frame, slave has configured a TX Response for 0x10.
LinFrame masterFrame;
masterFrame.id = 0x10;
masterFrame.checksumModel = LinChecksumModel::Enhanced;
masterFrame.dataLength = 8;
masterFrame.data = {'M', 'A', 'S', 'T', 'E', 'R', 0, 0};
// AUTOSAR API
master->SendFrame(masterFrame, LinFrameResponseType::MasterResponse);
}
else
{
// Alternative, non-AUTOSAR API
// Transmit the frame header, both master and slave have configured a TX Response for 0x11.
master->SendFrameHeader(0x11);
}
// In both cases (AUTOSAR and non-AUTOSAR), the following callbacks will be triggered:
// - LIN_TX_ERROR for the master and slave as both provided a response for the same LIN ID.
master_FrameStatusHandler(master, LinFrameStatusEvent{ timeEndOfFrame, masterFrame, LinFrameStatus::LIN_TX_ERROR });
slave_FrameStatusHandler(slave, LinFrameStatusEvent{ timeEndOfFrame, masterFrame, LinFrameStatus::LIN_TX_ERROR });
Erroneous Transmission from Slave to Master - No Response
This example shows what happens when a master initiates a transmission and no slave has configured a TX response for this LIN ID.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
// Slave Setup
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
slave->Init(slaveConfig);
// Register FrameStatusHandler
auto slave_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
slave->AddFrameStatusHandler(slave_FrameStatusHandler);
// NOTE: No TX response is configured for the slave
// ------------------------------------------------------------
// Master Setup
LinControllerConfig masterConfig;
masterConfig.controllerMode = LinControllerMode::Master;
masterConfig.baudRate = 20000;
master->Init(masterConfig);
// Register FrameStatusHandler to receive data from the LIN slave
auto master_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
master->AddFrameStatusHandler(master_FrameStatusHandler);
// ------------------------------------------------------------
// Perform TX from slave to master, i.e., the slave /is expected/
// to provide the frame response.
if (UseAutosarInterface)
{
// Use AUTOSAR interface to initiate the transmission.
LinFrame frameRequest;
frameRequest.id = 0x11;
frameRequest.checksumModel = LinChecksumModel::Enhanced;
master->SendFrame(frameRequest, LinFrameResponseType::SlaveResponse);
}
else
{
// Alternative, non-AUTOSAR API
// Transmit the frame header.
master->SendFrameHeader(0x11);
}
// ------------------------------------------------------------
// The following master callback will be triggered:
// - LIN_RX_NO_RESPONSE for the master, since no slave did provide a response
master_FrameStatusHandler(master, LinFrameStatusEvent{ timeEndOfFrame, frameRequest, LinFrameStatus::LIN_RX_NO_RESPONSE });
// The slave_FrameStatusHandler will not be called!
Erroneous Transmission from Slave to Master - Multiple Responses
This example shows what happens when a master initiates a transmission where multiple slaves have configured TX responses for the same LIN ID.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
// Slave 1 Setup (Sender)
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
// Setup LinFrameResponseMode::TxUnconditional for LIN ID 0x11 on slave1
LinFrame slaveFrame;
slaveFrame.id = 0x11;
slaveFrame.checksumModel = LinChecksumModel::Enhanced;
slaveFrame.dataLength = 8;
slaveFrame.data = {'S', 'L', 'A', 'V', 'E', 1, 0, 0};
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::TxUnconditional});
slave1->Init(slaveConfig);
// Register FrameStatusHandler to receive data
auto slave1_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
slave1->AddFrameStatusHandler(slave1_FrameStatusHandler);
// ------------------------------------------------------------
// Slave 2 Setup (Second Sender)
LinControllerConfig slave2Config;
slave2Config.controllerMode = LinControllerMode::Slave;
slave2Config.baudRate = 20000;
// Also setup LinFrameResponseMode::TxUnconditional for LIN ID 0x11 on slave2
LinFrame slaveFrame2;
slaveFrame2.id = 0x11;
slaveFrame2.checksumModel = LinChecksumModel::Enhanced;
slaveFrame2.dataLength = 8;
slaveFrame2.data = {'S', 'L', 'A', 'V', 'E', 1, 0, 0};
slaveConfig2.frameResponses.push_back(LinFrameResponse{slaveFrame2, LinFrameResponseMode::TxUnconditional});
slave2->Init(slave2Config);
// Register FrameStatusHandler to receive data
auto slave2_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
slave2->AddFrameStatusHandler(slave2_FrameStatusHandler);
// ------------------------------------------------------------
// Master Setup
LinControllerConfig masterConfig;
masterConfig.controllerMode = LinControllerMode::Master;
masterConfig.baudRate = 20000;
master->Init(masterConfig);
// Register FrameStatusHandler to receive confirmation of the successful transmission
auto master_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent& frameStatusEvent) {};
master->AddFrameStatusHandler(master_FrameStatusHandler);
// ------------------------------------------------------------
// Perform TX from slave to master, i.e., only one slave /is/
// /expected/ to provide the frame response. However, both
// slave1 and slave2 have done so.
if (UseAutosarInterface)
{
// Use AUTOSAR interface to initiate the transmission.
LinFrame frameRequest;
frameRequest.id = 0x11;
frameRequest.checksumModel = LinChecksumModel::Enhanced;
master->SendFrame(frameRequest, LinFrameResponseType::SlaveResponse);
}
else
{
// Alternative, non-AUTOSAR API
master->SendFrameHeader(0x11);
}
// ------------------------------------------------------------
// The following callbacks will be triggered:
// - LIN_RX_ERROR for the master, due to the collision
master_FrameStatusHandler(master, LinFrameStatusEvent{ timeEndOfFrame, frameRequest, LinFrameStatus::LIN_RX_ERROR });
// - LIN_TX_ERROR for both slaves
slave1_FrameStatusHandler(slave1, LinFrameStatusEvent{timeEndOfFrame, frameRequest, LinFrameStatus::LIN_TX_ERROR});
slave2_FrameStatusHandler(slave2, LinFrameStatusEvent{timeEndOfFrame, frameRequest, LinFrameStatus::LIN_TX_ERROR});
Go To Sleep
This example shows how to use GoToSleep()
and when the controller will switch from operational to sleep mode.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
// Slave Setup
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
slave->Init(slaveConfig);
// Register FrameStatusHandler to receive data
auto slave_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent frameStatusEvent) {};
slave->AddFrameStatusHandler(slave_FrameStatusHandler);
// Set sleep mode for the slave upon reception of a GoToSleep Frame
auto slave_GoToSleepHandler =
[](ILinController* slave, const LinGoToSleepEvent& goToSleepEvent) {
slave->GoToSleepInternal();
};
slave->AddGoToSleepHandler(slave_GoToSleepHandler);
// ------------------------------------------------------------
// Master Setup
LinControllerConfig masterConfig;
masterConfig.controllerMode = LinControllerMode::Master;
masterConfig.baudRate = 20000;
master->Init(masterConfig);
// Register FrameStatusHandler to receive confirmation of the successful transmission
auto master_FrameStatusHandler =
[](ILinController*, const LinFrameStatusEvent frameStatusEvent) {};
master->AddFrameStatusHandler(master_FrameStatusHandler);
// ------------------------------------------------------------
// Send a GoToSleep Frame to the LIN bus
master->GoToSleep();
// The master will enter sleep state immediately, i.e., the following condition is true:
assert(master->Status() == LinControllerStatus::Sleep);
// The slave will receive the go-to-sleep frame and trigger the callback:
slave_GoToSleepHandler(goToSleepEvent);
// the registered callback sets sleep state for the slave, after which also the slave is in sleep state:
assert(slave->Status() == LinControllerStatus::Sleep);
Note
The GoToSleepHandler
is triggered even without configuring ID 0x3C
for reception. However, the
FrameStatusHandler
for slaves is only called if ID 0x3C
is configured for reception. The master initiated
the sleep mode, it’s FrameStatusHandler
is called with LinFrameStatus::LIN_TX_OK
.
Wake Up
This example shows how to Wakeup()
a LIN bus. The example assumes that both master and slave are currently in sleep mode.
I.e., the situation corresponds to the end of the previous example.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
// Register a wake up handler. To receive wake up notifications.
// NB: this should be done when creating the controller!
// NB: receiving a wake up pulse does not automatically
// set the controller into operational state
auto master_WakeupHandler = [](ILinController* master, LinWakeupEvent wakeupEvent) { master->WakeupInternal(); };
master->AddWakeupHandler(master_WakeupHandler);
// ------------------------------------------------------------
// Send a wake up pulse to the LIN bus
slave->Wakeup();
// The slave will immediately enter operational state:
assert(slave->Status() == LinControllerStatus::Operational);
// The master will receive the wake up pulse and the registered callback is
// triggered by the controller:
master_WakeupHandler(LinWakeupEvent{ timestamp, master } );
// The registered callback puts the master back into operational state, i.e.:
assert(master->Status() == LinControllerStatus::Operational);
Aggregated view of responding LIN slaves (experimental)
This example shows how the LinSlaveConfigurationHandler
provides direct access to the LinFrameResponse
configuration of
all slaves. This can be used by a LIN master to predict if a slave response will be provided prior to the use of SendFrame()
or SendFrameHeader()
. It is primarily intended for diagnostic purposes and not required for regular operation of a LIN
controller. The calls AddLinSlaveConfigurationHandler, RemoveLinSlaveConfigurationHandler and GetSlaveConfiguration
reside in the SilKit::Experimental::Services::Lin namespace and might be changed or removed in future versions.
/* Copyright (c) 2022 Vector Informatik GmbH
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
// ------------------------------------------------------------
//
// Master Setup
using namespace SilKit::Services::Lin;
using namespace SilKit::Experimental::Services::Lin;
LinControllerConfig masterConfig;
masterConfig.controllerMode = LinControllerMode::Master;
masterConfig.baudRate = 20000;
master->Init(masterConfig);
// Define the LinSlaveConfigurationHandler
auto LinSlaveConfigurationHandler =
[](ILinController* master, LinSlaveConfigurationEvent frameResponseUpdateEvent)
{
// aggregatedSlaveConfig will contain
// LinSlaveConfiguration::respondingLinIds{ 0x11 }
auto aggregatedSlaveConfig = GetSlaveConfiguration(master);
};
AddLinSlaveConfigurationHandler(master, &LinSlaveConfigurationHandler);
// ------------------------------------------------------------
// Slave Setup
LinControllerConfig slaveConfig;
slaveConfig.controllerMode = LinControllerMode::Slave;
slaveConfig.baudRate = 20000;
// Setup a TX Response for LIN ID 0x11
LinFrame slaveFrame;
slaveFrame.id = 0x11;
slaveFrame.checksumModel = LinChecksumModel::Enhanced;
slaveFrame.dataLength = 8;
slaveFrame.data = {'S', 'L', 'A', 'V', 'E', 0, 0, 0};
slaveConfig.frameResponses.push_back(LinFrameResponse{slaveFrame, LinFrameResponseMode::TxUnconditional});
// LinSlaveConfigurationHandler handler is invoked
slave->Init(slaveConfig);
The experimental API is defined as follows:
-
auto SilKit::Experimental::Services::Lin::AddLinSlaveConfigurationHandler(SilKit::Services::Lin::ILinController *linController, SilKit::Experimental::Services::Lin::LinSlaveConfigurationHandler handler) -> SilKit::Util::HandlerId
Add a LinSlaveConfigurationHandler on a given controller that triggers when a remote LIN slave is changes its configuration.
This callback is mainly for diagnostic purposes and is NOT needed for regular LIN controller operation. It can be used to call GetSlaveConfiguration to keep track of LIN Ids, where a response of a LIN Slave is to be expected.
Requires Services::Lin::LinControllerMode::Master.
- Parameters
linController – The LIN controller to add the handler.
handler – The callback that is triggered upon a configuration update.
- Returns
Returns a SilKit::Util::HandlerId that can be used to remove the callback.
-
void SilKit::Experimental::Services::Lin::RemoveLinSlaveConfigurationHandler(SilKit::Services::Lin::ILinController *linController, SilKit::Util::HandlerId handlerId)
Remove a LinSlaveConfigurationHandler by HandlerId on a given controller.
Requires Services::Lin::LinControllerMode::Master.
- Parameters
linController – The LIN controller to remove the handler.
handlerId – Identifier of the callback to be removed. Obtained upon adding to respective handler.
-
auto SilKit::Experimental::Services::Lin::GetSlaveConfiguration(SilKit::Services::Lin::ILinController *linController) -> SilKit::Experimental::Services::Lin::LinSlaveConfiguration
Get the aggregated response configuration of all LIN slaves in the network.
Requires Services::Lin::LinControllerMode::Master.
- Parameters
linController – The LIN controller (master) to providing the view.
- Returns
A struct containing all LinIds on which LIN Slaves have configured Services::Lin::LinFrameResponseMode::TxUnconditional.