Concepts
Informative
The model behind the LIN driver: its per-channel state machine, how a frame transaction is processed, and how events are handled. Non-binding; the normative rules live in Lin — Requirements.
State machine
The driver has a driver-wide state and, within the initialized state, a per-channel power state.
Driver state
stateDiagram-v2
[*] --> LIN_DRV_STATE_UNINIT : Reset
LIN_DRV_STATE_UNINIT --> LIN_DRV_STATE_INIT : Lin_Init()
LIN_DRV_STATE_INIT --> LIN_DRV_STATE_UNINIT : Lin_DeInit()
Driver state |
Meaning |
API calls accepted |
|---|---|---|
|
Not initialized (state after reset/startup) |
Only |
|
Initialized; service APIs are accepted and every channel has a power state |
All |
Channel state
After Lin_Init every channel starts in SLEEP. The upper layer drives the channel between
SLEEP and OPERATIONAL; only in OPERATIONAL does the channel take part in bus traffic.
Lin_DeInit returns the whole driver (and its channels) to LIN_DRV_STATE_UNINIT.
stateDiagram-v2
direction LR
[*] --> LIN_CH_STATE_SLEEP : Lin_Init()
LIN_CH_STATE_SLEEP --> LIN_CH_STATE_OPERATIONAL : Lin_Wakeup() / Lin_WakeupInternal()
LIN_CH_STATE_OPERATIONAL --> LIN_CH_STATE_SLEEP : Lin_GoToSleepInternal()
Channel state |
Meaning |
Left via |
|---|---|---|
|
Channel initialized, not on the bus; wakeup-pulse detection enabled, hardware in low-power mode where supported |
|
|
Channel participates in the cluster; header reception and response TX/RX enabled |
|
Note
Lin_Wakeup (which also transmits a wakeup pulse) is only valid in SLEEP; calling it in
OPERATIONAL raises a development error. Use Lin_WakeupInternal to go operational
without sending a pulse (e.g. after an externally detected wakeup). See
Lin — Requirements (CHI-LIN-MUST-04).
Frame processing
A LIN frame has two parts. The header (break field, sync byte, protected identifier) is sent by the commander node; the response (data bytes plus checksum) may be sent by any node. As a responder, the driver receives every header and then acts on the response according to the upper layer’s decision:
The driver evaluates the received PID and passes it to the upper layer via
LinIf_OnHeader.The upper layer fills in the reaction, checksum model, and data length:
Reaction
The driver then…
LIN_REACTION_TXtransmits the response (data + checksum) provided by the upper layer.
LIN_REACTION_RXreceives the response and hands the data to the upper layer.
LIN_REACTION_IGNOREdoes nothing with the response and waits for the next header.
The checksum model is
LIN_CS_CLASSIC(data only) orLIN_CS_ENHANCED(data + PID). Data bytes are mapped byte 0 first (CHI-LIN-MUST-08).
The data buffer passed to/from the callbacks is valid only for the duration of the call — copy what you need to keep (CHI-LIN-MUST-09).
Event handling: interrupt or polling
For each channel, event handling is configured as either interrupt or polling:
Interrupt —
Lin_Initenables the LIN interrupt;Lin_Interruptservices it.Polling —
Lin_Initdisables the interrupt;Lin_PollFunctionservices the events.
Either way the same upper-layer callbacks are invoked: LinIf_OnHeader, LinIf_OnReception,
LinIf_OnTransmission, LinIf_OnError, and LinIf_OnWakeup.
State transition sequence
The sequence below shows initialization, the internal and external wakeup paths, and going back to sleep. This is the informative view of CHI-LIN-MUST-02, CHI-LIN-MUST-03, and CHI-LIN-MUST-11.
sequenceDiagram
participant ENV as Integration code
participant UPL as Upper layer
participant DRV as LinDrv
participant TRCV as LIN transceiver
participant HW as LIN HW
participant BUS as LIN BUS
Note over ENV,BUS: LIN_DRV_STATE_UNINIT -> LIN_DRV_STATE_INIT
activate UPL
UPL ->> DRV: Lin_Init ()
activate DRV
DRV->> HW : Initialization (configuration)
opt IF LIN HW supports a low power mode
DRV->> HW: Set into a low power mode
end
opt IF "wakeup detection" is enabled
DRV->> HW: Setup to detect wakeup pulse
end
DRV->> DRV: Channel state to LIN_CH_STATE_SLEEP
DRV-->> UPL: ;
deactivate DRV
deactivate UPL
Note over ENV,BUS: LIN_CH_STATE_SLEEP -> LIN_CH_STATE_OPERATIONAL
alt IF Internal (Top-Down) wakeup
activate UPL
UPL ->> DRV: Lin_Wakeup(channel)
activate DRV
DRV ->> HW: Enable interrupt (wakeup pulse detection or wakeup pulse TX completion)
DRV ->> HW: Send wakeup pulse
HW ->> BUS: wakeup pulse
DRV->> DRV: Channel state to LIN_CH_STATE_OPERATIONAL
DRV -->> UPL: return Std_ReturnType
deactivate DRV
deactivate UPL
note left of HW: If HW supports receiving back of wakeup pulse, use it.<br/> Otherwise, use wakeup pulse TX completion.
HW ->> DRV : Lin_Interrupt (wakeup pulse detection or wakeup pulse TX completion)
activate DRV
opt IF HW settting change after wakeup pulse transmission is needed
DRV ->> HW: Change HW setting to enable header reception
end
DRV ->> UPL: LinIf_OnWakeup(channel)
activate UPL
UPL -->> DRV : return
deactivate UPL
DRV -->> HW : return from interrupt
deactivate DRV
note left of UPL: In case of re-transmission of wakeup pulse.<br/> (e.g. commander does not start scheduler within the specific time period)<br/> In this case, the upper layer should call Lin_GoToSleepInternal(),<br/> then call Lin_Wakeup() again.
else IF External (Bottom-Up) wakeup
opt IF use wakeup detetion by transceiver
BUS -) TRCV: wakeup pulse
TRCV -) ENV: Interrupt handler (typically edge detection)
activate ENV
ENV ->> UPL: A related interface
activate UPL
UPL ->> DRV: Lin_WakeupInternal(channel)
activate DRV
DRV ->> HW: Change HW setting to enable header reception
DRV->> DRV: Channel state to LIN_CH_STATE_OPERATIONAL
DRV -->> UPL: return Std_ReturnType
deactivate DRV
UPL -->> ENV: ;
deactivate UPL
ENV --) TRCV : return from interrupt
deactivate ENV
end
opt IF "wakeup detection" is enabled (detect by LinDrv)
BUS -) HW: wakeup pulse
HW ->> DRV: Lin_Interrupt
activate DRV
DRV ->> UPL: LinIf_OnWakeup(channel)
activate UPL
UPL ->> DRV: Lin_WakeupInternal(channel)
activate DRV
DRV ->> HW: Change HW setting to enable header reception
DRV->> DRV: Channel state to LIN_CH_STATE_OPERATIONAL
DRV -->> UPL: return Std_ReturnType
deactivate DRV
UPL -->> DRV: ;
deactivate UPL
DRV -->> HW : return from interrupt
deactivate DRV
end
end
Note over ENV,BUS: LIN_CH_STATE_OPERATIONAL -> LIN_CH_STATE_SLEEP
activate UPL
UPL ->> DRV: Lin_GoToSleepInternal (channel)
activate DRV
opt IF LIN HW supports a low power mode
DRV->> HW: Set into a low power mode
end
opt IF "wakeup detection" is enabled
DRV->> HW: Setup to detect wakeup pulse
end
DRV->> DRV: Channel state to LIN_CH_STATE_SLEEP
DRV-->> UPL: return Std_ReturnType
deactivate DRV
deactivate UPL
Transaction sequence
Once a channel is OPERATIONAL, each Lin_Interrupt (or Lin_PollFunction call) fans out by
event type. This is the informative view of CHI-LIN-MUST-12 and CHI-LIN-MUST-13.
sequenceDiagram
participant UPL as Upper layer
participant DRV as LinDrv
participant HW as LIN HW
participant BUS as LIN BUS
Note over UPL,BUS: In LIN_CH_STATE_OPERATIONAL state
HW ->> DRV: Lin_Interrupt
activate DRV
alt IF error has been detected
DRV ->> HW: Setup for next header reception if HW setup is needed
DRV ->> UPL: LinIf_OnError(channel, error)
activate UPL
UPL -->> DRV: ;
deactivate UPL
else IF header reception
DRV ->> HW: Get PID
DRV ->> DRV: Setup pduInfoPtr (pid=PID, sduPtr=Internal buffer)
DRV ->> UPL: LinIf_OnHeader(channel, pduInfoPtr)
activate UPL
UPL ->> UPL: Setup pduInfoPtr (cs, reaction, dl)
UPL ->> UPL: Setup TX data in pduInfoPtr.sduPtr (in case of TX)
UPL -->> DRV: ;
deactivate UPL
alt IF pduInfoPtr->>reaction == TX
DRV ->> HW: Send response
HW ->> BUS: response
else IF pduInfoPtr->>reaction == RX
DRV ->> HW: Setup HW to receive response
else IF pduInfoPtr->>reaction == IGNORE
DRV ->> HW: Setup for next header reception if HW setup is needed
end
else IF RX response
DRV ->> HW : Get response and store it to buffer pointed by sduPtr
DRV ->> HW: Setup for next header reception if HW setup is needed
DRV ->> UPL: LinIf_OnReception(channel, sduPtr)
activate UPL
UPL -->> DRV: ;
deactivate UPL
else IF TX response completion
DRV ->> HW: Setup for next header reception if HW setup is needed
DRV ->> UPL: LinIf_OnTransmission(channel)
activate UPL
UPL -->> DRV: ;
deactivate UPL
end
DRV -->> HW: return from interrupt
deactivate DRV
Key terms
For LIN glossary terms — commander/responder node, header, response, protected identifier (PID), checksum model, reaction, wakeup pulse — see the glossary in the appendix.