© ISO 2016 Road vehicles — Local Interconnect Network (LIN) — Part 5 Application programmers interface (API) Véhicules routiers — Réseau Internet local (LIN) — Partie 5 Interface du programmeur d’appl[.]
Terms and definitions
This document adheres to the terms and definitions outlined in ISO 17987-2 and ISO 17987-3 For standardization purposes, ISO and IEC provide terminological databases accessible at specified addresses.
— IEC Electropedia: available at http://www.electropedia.org/
— ISO Online browsing platform: available at http://www.iso.org/obp
Symbols
Abbreviated terms
API application programmers interface ms millisecond
RX Rx pin of the transceiver
UART universal asynchronous receiver transmitter
LIN cluster generation
The LIN Description file (LDF), as outlined in ISO 17987-2, is utilized by a tool to create a configuration for the LIN device driver The node capability language specification (NCF) is typically excluded from this process, as it is designed to describe a hardware slave node and does not require the API For a detailed overview of the workflow and the functions of the LDF and NCF, refer to ISO 17987-2.
Concept of operations
General
The API is split in three areas
— LIN node configuration and identification API, and
— LIN transport layer API (optional).
LIN core API
The LIN core API simplifies the interaction between the application and the LIN core by managing initialization and processing, allowing the application to focus on higher-level functions without worrying about frame handling and transmission Additionally, it includes notifications for detecting specific frame transfers when needed, and provides API calls for controlling the LIN core effectively.
Two versions exist of most of the API calls
— static calls embed the name of the signal or interface in the name of the call, and
— dynamic calls provide the signal or interface as a parameter.
NOTE The named objects (signals, schedules) defined in the LDF extends their names with the channel postfix name (see channel postfix name definition in ISO 17987-2).
LIN node configuration and identification API
The LIN node configuration and identification API operates on a service-based request/response model, where the master node application sends a request to a designated slave node and waits for a response The device driver on the slave node manages the service automatically.
The behaviour of the LIN node configuration and identification API is covered in the node configuration and identification (see ISO 17987-3).
LIN transport layer API
The LIN transport layer operates on a message-based system, designed to serve as a transport layer for messages directed to a diagnostic message parser beyond the LIN device driver It offers two distinct APIs: a raw API that grants applications complete control over the contents of each frame sent, and a message-based API that handles the entire transport layer functionality.
The behaviour of the LIN transport layer API is defined in ISO 17987-2.
API conventions
General
The LIN core API features a collection of functions designed to establish a distinct namespace, thereby reducing the likelihood of conflicts with existing software Each function and type is prefixed to ensure clarity and organization.
“l_” (lowercase “L” followed by an “underscore”).
DRIVER AND CLUSTER MANAGEMENT l_sys_init Performs the initialization of the LIN core.
The SIGNAL INTERACTION feature includes functions for scalar signal operations, allowing users to read and write the current value of the signal Additionally, it provides byte array operations to read the current values of selected bytes in the signal and to write new values to those bytes, specified by the name "sss."
The function `l_flg_tst` returns a boolean value indicating the current state of a specified flag, with a return of zero signifying that the flag is cleared, while a non-zero return indicates that the flag is active Conversely, the function `l_flg_clr` sets the value of the specified flag to zero, effectively clearing it.
SCHEDULE MANAGEMENT l_sch_tick Function provides a time base for scheduling. l_sch_set Sets up the next schedule.
The interface management functions include l_ifc_init, which initializes the controller by setting up internal functions like the baud rate The l_ifc_goto_sleep function requests slave nodes in the cluster to enter bus sleep mode, while l_ifc_wake_up transmits a wake-up signal The l_ifc_ioctl function manages functionalities not addressed by other API calls Both l_ifc_rx and l_ifc_tx require the application program to bind the interrupt and set the correct interface handle if interrupts are utilized The l_ifc_aux function helps slave nodes synchronize with the break field/sync byte sequence from the master node, and l_ifc_read_status returns the status of the previous communication.
The user-defined function `l_sys_irq_disable` effectively disables interrupts from LIN communication, ensuring a stable state Conversely, the `l_sys_irq_restore` function is utilized to restore the previously configured interrupt level, allowing for the resumption of normal operations.
The NODE CONFIGURATION service includes several important calls: `ld_is_ready` checks the status of the last configuration request, while `ld_check_response` provides the result of the last configuration service The `ld_assign_frame_id_range` function assigns protected identifiers for up to four frames in the slave node with the configured NAD Additionally, `ld_assign_NAD` sets the configured node diagnostic address (NAD) for all slave nodes that match the initial NAD, supplier ID, and function ID The `ld_save_configuration` call requests to save the configuration to a specific slave node or broadcasts to all if the broadcast NAD is set The `ld_read_configuration` function serializes the current configuration and copies it to a specified data pointer, and `ld_set_configuration` configures the NAD and PIDs based on the provided settings.
The ld_read_by_id function requests the selected slave node, identified by the configured NAD, to return the property linked to the specified id parameter Additionally, the ld_read_by_id_callout is utilized when the master node sends a read request using an identifier from the user-defined area.
INITIALIZATION ld_init This call reinitializes the raw or messaged-based layer on the interface.
The RAW API provides several functions for data transmission and reception The `ld_put_raw` function queues 8 bytes of data for transmission in the next available MasterReq frame The `ld_get_raw` function copies the oldest received diagnostic frame data to a specified memory location Additionally, `ld_raw_tx_status` returns the status of the raw frame transmission, while `ld_raw_rx_status` provides the status of the raw frame reception.
The MESSAGE-BASED API includes several key functions: `ld_send_message`, which packages information into diagnostic frames; `ld_receive_message`, which sets up the LIN diagnostic module to receive and store messages; `ld_tx_status`, which provides the status of the last `ld_send_message` call; and `ld_rx_status`, which returns the status of the last `ld_receive_message` call.
Data types
The LIN core defines the following types:
— l_bool 0 is false, and non-zero (>0) is true;
— l_signal_handle has character string type “signal name”.
In order to gain efficiency, the majority of the functions are static functions (no parameters are needed, since one function exist per signal, per interface, etc.).
Driver and cluster management
Table 2 defines the l_sys_init.
Prototype l_bool l_sys_init (void)
Applicability Master and slave nodes.
The function l_sys_init is responsible for initializing the LIN core, specifically focusing on the physical node, which encompasses the entire node as defined in ISO 17987-2 It is essential to call l_sys_init first before utilizing any other API functions within the LIN core.
Return value Zero if the initialization succeeded.
Non-zero if the initialization failed.
Signal interaction
In all signal API calls below the sss is the name of the signal, e.g l_u8_rd_enginespeed ().
The signals are of three different types:
— l_bool for one bit signals; zero if false, non-zero otherwise;
— l_u8 for signals of the size 2 bits to 8 bits;
— l_u16 for signals of the size 9 bits to 16 bits.
Table 3 defines the scalar signal read.
Dynamic prototype l_bool l_bool_rd (l_signal_handle sss); l_u8 l_u8_rd (l_signal_handle sss); l_u16 l_u16_rd (l_signal_handle sss);
Static prototype l_bool l_bool_rd_sss (void); l_u8 l_u8_rd_sss (void); l_u16 l_u16_rd_sss (void);
Applicability Master and slave nodes.
Description Reads and returns the current value of the signal.
Table 4 defines the scalar signal write.
Dynamic prototype void l_bool_wr (l_signal_handle sss, l_bool v); void l_u8_wr (l_signal_handle sss, l_u8 v); void l_u16_wr (l_signal_handle sss, l_u16 v);
Static prototype void l_bool_wr_sss (l_bool v); void l_u8_wr_sss (l_u8 v); void l_u16_wr_sss (l_u16 v);
Applicability Master and slave nodes.
Description Sets the current value of the signal to v.
Table 5 defines the byte array read.
Dynamic prototype void l_bytes_rd (l_signal_handle sss, l_u8 start, /* first byte to read from */ l_u8 count, /* number of bytes to read */ l_u8* const data); /* where data is written */
Static prototype void l_bytes_rd_sss (l_u8 start, l_u8 count, l_u8* const data);
Applicability Master and slave nodes.
The function reads and returns the current values of the specified bytes in the signal, ensuring that the sum of the start and count parameters does not exceed the length of the byte array.
In a byte array of 6 bytes, indexed from 0 to 5, reading bytes 2 and 3 reveals that the parameter value starts at 2, effectively skipping bytes 0 and 1, while also determining the count.
2 (reading byte 2 and 3) In this case byte 2 is written to data [0] and byte 3 is written to data [1].
Table 6 defines the byte array write.
Dynamic prototype void l_bytes_wr (l_signal_handle sss, l_u8 start, /* first byte to write to */ l_u8 count, /* number of bytes to write */ const l_u8* const data); /* where data is read from */
Static prototype void l_bytes_wr_sss (l_u8 start, l_u8 count, const l_u8* const data);
Applicability Master and slave nodes.
Description Sets the current value of the selected bytes in the signal specified by the name sss to the value specified.
The sum of start and count are never greater than the length of the byte array, although the device driver does not choose to enforce this in runtime.
In a byte array of 7 bytes, indexed from 0 to 6, writing bytes 3 and 4 indicates that the starting parameter value is 3, as it skips bytes 0, 1, and 2, while the count is 2, corresponding to the written bytes 3 and 4 Consequently, byte 3 is retrieved from data[0] and byte 4 from data[1].
Notification
Flags are local objects within a node that synchronize the application program with the LIN core Automatically set by the LIN core, these flags can only be tested or cleared by the application program They are associated with all types of frames, and a flag is activated when a frame or signal is transmitted or received, as outlined in ISO 17987-3.
Three types of flags can be created:
— a flag that is attached to a signal,
— a flag that is attached to a frame, and
— a flag that is attached to a signal in a particular frame This is used when a signal is packed into multiple frames.
All three listed flag types above are applicable on both transmitted and received signals/frames.
Table 7 defines the I_flg_tst.
Dynamic prototype l_bool l_flg_tst (l_flag_handle fff)
Static prototype l_bool l_flg_tst_fff (void);
Where fff is the name of the flag, e.g l_flg_tst_RxEngineSpeed ().
Applicability Master and slave nodes.
Description Returns a C boolean indicating the current state of the flag specified by the name fff, i.e returns zero if the flag is cleared, non-zero otherwise.
Example A flag named tx confirmation is attached to a published signal valve position stored in the
IO_1 frame The static implementation of the l_flg_tst is: l_bool l_flg_tst_txconfirmation (void);
The flag is set when the IO_1 frame (containing the signal value position) is successfully transmitted from the node.
Reference No reference, flags are API specific and not described anywhere else.
Table 8 defines the l_flg_clr.
Dynamic prototype void l_flg_clr (l_flag_handle fff);
Static prototype void l_flg_clr_fff (void);
Where fff is the name of the flag, e.g l_flg_clr_RxEngineSpeed ().
Applicability Master and slave nodes.
Description Sets the current value of the flag specified by the name fff to zero.
Reference No reference, flags are API specific and not described anywhere else.
Schedule management
Table 9 defines the l_sch_tick.
Dynamic prototype l_u16 l_sch_tick (l_ifc_handle iii);
Static prototype l_u16 l_sch_tick_iii (void); where iii is the name of the interface, e.g l_sch_tick_MyLinIfc ().
The l_sch_tick function serves as a time base for the LIN driver’s scheduler, initiating the transmission of a frame when it becomes due Once the end of the current schedule is reached, l_sch_tick resets and begins the schedule anew.
The l_sch_tick function is invoked periodically for each interface within the node, with the period defined by the time base specified in ISO 17987-3:2016, section 5.3, and set in the LDF as outlined in section 12.3.4.2 This periodic call establishes the time base tick, making it crucial to maintain the time base period with minimal jitter.
The invocation of l_sch_tick initiates the transition to the next frame and updates the signal values for any signals received since the last call, as outlined in ISO 17987-3:2016, section 5.1.5.
Return value Zero, if the next call of l_sch_tick does not start transmission of a frame.
The return value of l_sch_tick is non-zero if the subsequent call initiates the transmission of a frame in the next entry of the schedule table In this scenario, the return value corresponds to the number of the next schedule table entry, counted from the start of the table, and falls within the range of 1 to N, where N represents the total number of entries in the schedule table.
Table 10 defines the l_sch_set.
Dynamic prototype void l_sch_set (l_ifc_handle iii, l_schedule_handle schedule, l_u16 entry);
Static prototype void l_sch_set_iii (l_schedule_handle schedule, l_u16 entry); where iii is the name of the interface, e.g l_sch_set_MyLinIfc (MySchedule1, 0).
The l_sch_tick function establishes the upcoming schedule for a specific interface, denoted as "iii." This new schedule takes effect immediately when the current schedule reaches its next entry point The interface name "iii" is optional and is designed to prevent naming conflicts when the node serves as a master for multiple LIN clusters.
The entry specifies the initial point in the new schedule table, with values ranging from 0 to N, where N represents the total number of entries If the entry is either 0 or 1, the new schedule table begins from the start.
A predefined schedule table, L_NULL_SCHEDULE, exists and is used to stop all transfers on the LIN cluster.
The entry value can be utilized alongside the l_sch_tick return value to temporarily pause one schedule in favor of another, allowing for a seamless transition back to the original schedule at the exact point of interruption.
Interface management
Interface management oversees the specific interfaces, which are the logical channels to the bus Each interface is uniquely identified by its interface name, marked with the iii extension for every API call The process of setting the interface name (iii) is beyond the scope of this document.
Table 11 defines the l_ifc_init.
Dynamic prototype l_bool l_ifc_init (l_ifc_handle iii)
Static prototype l_bool_ifc_init_iii (void);
Where iii is the name of the interface, e.g l_ifc_init_MyLinIfc ().
Applicability Master and slave nodes.
The function l_ifc_init initializes the specified controller by name, configuring essential internal functions like the baud rate By default, the l_ifc_init call establishes the L_NULL_SCHEDULE in a master node, resulting in no frames being sent or received.
The initial call a user makes before utilizing any other LIN API functions is crucial This function indicates success by returning zero, while a non-zero return value signifies a failure For a comprehensive overview of the interface concept, please refer to the concept of operation.
Table 12 defines the l_ifc_goto_sleep.
Dynamic prototype void l_ifc_goto_sleep (l_ifc_handle iii)
Static prototype void l_ifc_goto_sleep_iii (void);
Where iii is the name of the interface, e.g l_ifc_goto_sleep_MyLinIfc ().
Description This call requests slave nodes on the cluster connected to the interface to enter bus sleep mode by issuing one go to sleep command, see ISO 17987-2:2016, 5.4.
The go to sleep command is scheduled latest when the next schedule entry is due.
The l_ifc_goto_sleep does not affect the power mode It is up to the application to do this.
If the go to sleep command was successfully transmitted on the cluster the go to sleep bit is set in the status register, see ISO 17987-2:2016, 5.4.
Table 13 defines the l_ifc_wake_up.
Dynamic prototype void l_ifc_wake_up (l_ifc_handle iii)
Static prototype void l_ifc_wake_up_iii (void); where iii is the name of the interface, e.g l_ifc_wake_up_MyLinIfc ().
Applicability Master and slave nodes.
The function sends a single wake-up signal immediately upon being called It is the application's duty to retransmit this wake-up signal in accordance with the wake-up sequence specified in ISO 17987-2.
Table 14 defines the l_ifc_ioctl.
The dynamic prototype for the function is defined as \$l\_u16 l\_ifc\_ioctl (l\_ifc\_handle iii, l\_ioctl\_op op, void* pv)\$, while the static prototype is \$l\_u16 l\_ifc\_ioctl\_iii (l\_ioctl\_op op, void* pv)\$ In this context, \$iii\$ represents the name of the interface, such as \$l\_ifc\_ioctl\_MyLinIfc (MyOp, &MyPars)\$.
Applicability Master and slave nodes.
This function manages features not addressed by other API calls, specifically for protocol and hardware-related parameters An example of its functionality includes the ability to enable or disable wake-up signal detection.
The iii interface is where the operation defined in op is applied, while the pointer pv refers to an optional parameter supplied to the function.
Exactly which operations that are supported is implementation dependent.
Reference No reference, the behaviour is API specific and not described anywhere else.
Table 15 defines the l_ifc_rx.
Dynamic prototype void l_ifc_rx (l_ifc_handle iii)
Static prototype void l_ifc_rx_iii (void); where iii is the name of the interface, e.g l_ifc_rx_MyLinIfc ().
Applicability Master and slave nodes.
Description The application program is responsible for binding the interrupt and for setting the correct interface handle (if interrupt is used).
In UART-based systems, a user-defined interrupt handler is invoked when a UART receives a single character of data, allowing the function to execute essential operations on the UART control registers.
For more complex LIN hardware, it is used to indicate the reception of a complete header or frame.
Reference No reference, the behaviour is API specific and not described anywhere else.
Table 16 defines the l_ifc_tx.
Dynamic prototype void l_ifc_tx (l_ifc_handle iii)
Static prototype void l_ifc_tx_iii (void); where iii is the name of the interface, e.g l_ifc_tx_MyLinIfc ().
Applicability Master and slave nodes.
Description The application program is responsible for binding the interrupt and for setting the correct interface handle (if interrupt is used).
In UART-based systems, a user-defined interrupt handler is invoked when a UART transmits a character of data, allowing the function to execute essential operations on the UART control registers.
For more complex LIN hardware, it is used to indicate the transmission of a complete frame.Reference No reference, the behaviour is API specific and not described anywhere else.
Table 17 defines the l_ifc_aux.
Dynamic prototype void l_ifc_aux (l_ifc_handle iii)
Static prototype void l_ifc_aux_iii (void);
Where iii is the name of the interface, e.g l_ifc_aux_MyLinIfc ().
Applicability Master and slave nodes.
This function enables slave nodes to synchronize with the break field or sync byte field sequence sent by the master node over the specified interface.
A user-defined interrupt handler is triggered by edge detection on a hardware pin linked to the interface iii, while l_ifc_aux is exclusively utilized in a slave node.
This function is strongly hardware connected and the exact implementation and usage is implementation dependent.
This function might even be empty in cases where the break field/sync byte field sequence detection is implemented in the l_ifc_rx function.
Reference No reference, the behaviour is API specific and not described anywhere else.
Table 18 defines the l_ifc_read_status.
Dynamic prototype l_u16 l_ifc_read_status (l_ifc_handle iii)
Static prototype l_u16 l_ifc_read_status_iii (void); where iii is the name of the interface, e.g l_ifc_read_status_MyLinIfc ().
Applicability Master and slave nodes The behaviour is different for master and slave nodes, see de- scription below.
Description This function returns the status of the previous communication The call returns the status word (16 bit value), as shown in Table 19.
Table 19 defines the return value of l_ifc_read_status (bit 15 is MSB, bit 0 is LSB).
Table 19 — Return value o f l_i f c_read_status (bit 15 is MSB, bit 0 is LSB).
Errors in the header can lead to the frame being ignored, as the header will not be recognized Additionally, if there is no response to a received frame, it remains unset Furthermore, the status is not updated in the event of a response collision for an event-triggered frame.
Successful transfer is set if a frame has been transmitted/received without an error.
Overrun occurs when two or more frames are processed since the last call to l_ifc_read_status In such instances, the error in response and successful transfer are logically ORed for all processed frames.
The "go to sleep" command is activated in a slave node upon receipt and in a master node once the command is successfully transmitted over the bus Importantly, the power mode remains unchanged after the command is received, as this process is managed within the application.
Bus activity is defined as the detection of communication on the bus, as outlined in ISO 17987-2 A slave node transitions to bus sleep mode after a specified duration of inactivity on the bus This functionality can be implemented by applications that monitor bus activity, highlighting the distinction between bus activity and inactivity.
User provided call outs
The application features a set of functions, referred to as implementation dependent, that are invoked within the LIN module to disable LIN communication interrupts during specific internal operations and restore the previous state afterward These functions can be utilized in the l_sch_tick function, and the application itself also leverages their capabilities.
Table 22 defines the l_sys_irq_disable.
Table 22 — l_sys_irq_disable Prototype l_irqmask l_sys_irq_disable (void)
Applicability Master and slave nodes.
Prototype void l_sys_irq_restore (l_irqmask previous)
Applicability Master and slave nodes.
Description The user implementation of this function restores the interrupt level identified by the provided l_irqmask previous.
Reference No reference, the behaviour is API specific and not described anywhere else.
Node configuration and identification
Overview
The node configuration and diagnostic API features a collection of functions designed to operate within a distinct namespace, reducing the likelihood of conflicts with existing software Each function and type is prefixed with "ld_" to ensure clarity and organization.
In node configuration operations, the scheduling of the master request frame and slave response frame is essential If the master node disregards the responses to its requests, only the master request frame will be included in the schedule table.
Node configuration
Table 24 defines the ld_is_ready.
Prototype l_u8 ld_is_ready (l_ifc_handle iii)
Description This call returns the status of the last requested configuration service.
Return value LD_SERVICE_BUSY:
The configuration request has been completed This is an intermediate status between the configuration request and configuration response.
The configuration request and response have been successfully completed, indicating that the response is valid and has been analyzed Additionally, the value LD_SERVICE_ERROR is returned if no request has been made yet.
The configuration request or response experienced an error Error here means error on the bus, and not a negative configuration response from the slave node.
Reference No reference, the behaviour is API specific and not described anywhere else.
Figure 2 illustrates a successful configuration request and response scenario, highlighting that the state change occurs with a delay of one time base after the completion of the master request frame and the slave response frame.
Figure 2 — Success f ul configuration request and configuration response
Table 25 defines the ld_check_response.
Prototype void ld_check_response (l_ifc_handle iii, l_u8* const RSID, l_u8* const error_code) Applicability Master node only.
This call retrieves the outcome of the most recent node configuration service, providing the parameters RSID and error_code While RSID will always return a value, error_code may not The default values for both RSID and error_code are set to 0 (zero).
Reference No reference, the behaviour is API specific and not described anywhere else.
4.4.2.3 ld_assign_frame_id_range
Table 26 defines the ld_assign_frame_id_range.
Table 26 — ld_assign_ f rame_id_range
Prototype void ld_assign_frame_id_range (l_ifc_handle iii, l_u8 NAD, l_u8 start_index, const l_u8* const PIDs) Applicability Master node only.
This call assigns the protected identifier (PID) for up to four frames in the slave node using the configured Network Address Device (NAD) The PIDs parameter consists of four bytes, with each byte representing a PID, while any unused values can be disregarded or left unassigned.
Table 27 defines the ld_assign_NAD.
Prototype void ld_assign_NAD (l_ifc_handle iii, l_u8 initial_NAD, l_u16 supplier_id, l_u16 function_id, l_u8 configured_NAD) Applicability Master node only.
Description This call assigns the configured_NAD to the slave nodes that matches the initial_NAD, the supplier_id and the function_id.
Reference See the definition of the service assign NAD, see ISO 17987-3.
Table 28 defines the ld_save_configuration.
Prototype void ld_save_configuration (l_ifc_handle iii, l_u8 NAD) Applicability Master node only.
Description This call makes a save configuration request to a specific slave node with the given con- figured NAD, or to all slave nodes if broadcast NAD is set.
Reference See the definition of the save configuration service in ISO 17987-3 API call l_ifc_read_status see 4.3.7.9 and example in 4.6.
Table 29 defines the ld_read_configuration.
Prototype l_u8 ld_read_configuration (l_ifc_handle iii, l_u8* const data, l_u8* const length) Applicability Slave node only.
Description This function does not transport anything on the bus.
This function serializes the current configuration and copies it to the specified data pointer provided by the application It should be invoked when the save configuration request flag is set in the status register, as detailed in section 4.3.7.9 Once the function completes, the application must store the data in the appropriate memory.
The caller allocates a data area of a specified length prior to invoking this function, which then updates the length parameter to reflect the actual size of the configuration If the data area is insufficient, the function exits without making any changes.
If the NAD has not been established through a prior call to ld_set_configuration or if the master node has utilized the configuration services, the configured NAD will retain its initial value.
The data consists of the configured Network Address (NAD) followed by the Parameter Identifiers (PIDs), with each occupying one byte The structure is organized with the configured NAD first, followed by all PIDs corresponding to the frames The sequence of the PIDs aligns with the frame list in the LDF and the frame definitions in the NCF, as specified in ISO 17987-2.
Return value LD_READ_OK:
If the service was successful.
If the configuration size is greater than the length It means that the data area does not contain a valid configuration.
Reference See the definition of the save configuration service in ISO 17987-3.
Function l_ifc_read_status see 4.3.7.9 and example in 4.6.
Table 30 defines the ld_set_configuration.
Prototype l_u8 ld_set_configuration (l_ifc_handle iii, const l_u8* const data, l_u16 length) Applicability Slave node only.
Description This call does not transport anything on the bus.
The function configures the NAD and PIDs based on the provided data configuration It is designed to either restore a saved configuration or establish an initial configuration, such as one defined by I/O pins This function is invoked following the l_ifc_init call.
The caller sets the size of the data area before calling the function.
The data consists of the configured Network Address (NAD) and Parameter Identifiers (PIDs), each occupying one byte The structure is organized with the NAD followed by all PIDs for the frames, maintaining the same order as specified in the frame list of the LDF and the frame definition in the NCF, as outlined in ISO 17987-2.
Return value LD_SET_OK:
If the service was successful.
If the size of the configuration is not equal to the given length.
The set of configuration could not be made.
Reference See the definition of the save configuration service in ISO 17987-3.
Function l_ifc_read_status, see 4.3.7.9 and example in 4.6.
Identification
Table 31 defines the ld_read_by_id.
Table 31 — ld_read_by_id
Prototype void ld_read_by_id (l_ifc_handle iii, l_u8 NAD, l_u16 supplier_id, l_u16 function_id, l_u8 id, l_u8* const data);
The call requests the selected slave node, identified by the NAD, to return the property linked to the specified id parameter, as detailed in ISO 17987-3:2016, Table 20 Once the subsequent call to ld_is_ready indicates LD_SERVICE_IDLE following the ld_read_by_id call, the RAM area indicated by data will contain between one and five bytes of data based on the request.
The results are provided in big endian format, requiring little endian CPUs to swap the bytes, rather than relying on the LIN diagnostic driver This choice of big endian data facilitates easier message routing to a backbone network, such as CAN.
Reference See definition of the ReadByIdentifier service in ISO 17987-3.
4.4.3.2 ld_read_by_id_callout
Table 32 defines the ld_read_by_id_callout.
Table 32 — ld_read_by_id_callout
The optional callout function `ld_read_by_id_callout` is applicable only in slave nodes It is implemented by the slave node application when a user-defined read by identifier request is utilized.
This callout is triggered when the master node sends a ReadByIdentifier request containing an identifier within the user-defined area Upon receiving this request, the driver invokes the slave node application.
The id parameter is the identifier in the user defined area (32 to 63), see ISO 17987-3:2016, Table 18 from the ReadByIdentifier configuration request.
The data pointer references a 5-byte data area utilized by the application to configure the positive response, as outlined in the user-defined area of ISO 17987-3:2016, Table 19.
Return value LD_NEGATIVE_RESPONSE:
The slave node responds with a negative response as defined in ISO 17987-3:2016, Table 20
In this case, the data area is not considered.
The slave node sets up a positive response using the data provided by the application. LD_NO_RESPONSE:
The slave node does not answer.
Transport layer
Overview
The LIN transport layer API features a collection of functions designed to create a distinct namespace, reducing the likelihood of conflicts with existing software Each function and type is prefixed with "ld_" to ensure clarity and organization.
The LIN diagnostic transport layer API requires an understanding of the underlying protocol, as detailed in ISO 17987-2 This transport layer is designed to facilitate the transmission of diagnostic requests and responses from test equipment on a backbone network, such as CAN, to LIN slave nodes through the master node.
Raw- and messaged-based API
The raw API, designed for ISO 15765-2 PDUs on CAN, closely resembles LIN diagnostic frames and operates on a frame/PDU basis, allowing applications to manage PCI information This API facilitates communication with the CAN transport layer, enabling efficient gatewaying of diagnostic requests and responses between CAN and LIN with minimal effort and resources A key requirement for utilizing the raw API is that the CAN frame format must match that of LIN, with addressing information located in the first byte.
The message-based API operates by utilizing a message buffer pointer, allowing for efficient data transfer During this process, the LIN driver functions as a transport layer, handling the packing and unpacking of messages This functionality is particularly beneficial for slave nodes, which focus on parsing messages rather than routing them.
Both raw API and the messaged-based API use the same structure of the diagnostic frames, i.e NAD, PCI, SID, etc.
Initialization
Table 33 defines the ld_init.
Prototype void ld_init (l_ifc_handle iii)
Applicability Master and slave nodes.
This function (re)initializes the raw or message-based layers on interface iii, ensuring that all transport layer buffers are set up Importantly, if a diagnostic frame is currently in progress, transporting either a message-based or raw message on the bus, it will not be interrupted.
Reference No reference, the behaviour is API specific and not described anywhere else.
Overview
The raw API functions at the PDU level, primarily facilitating the gateway of PDUs between CAN and LIN networks To manage varying bus speeds effectively, a FIFO buffer is commonly employed to store PDUs.
Table 34 defines the ld_put_raw.
Prototype void ld_put_raw (l_ifc_handle iii, const l_u8* const data)
Description The call queues the transmission of 8 bytes of data in one frame The data is sent in the next suitable frame (MasterReq frame).
The data area is copied in the call, the pointer is not memorized.
If no more queue resources are available, the data is jettisoned and the appropriate error status is set.
Reference The raw and messaged-based is not differentiated outside the API A general description of the transport layer can be found in ISO 17987-2.
Table 35 defines the ld_get_raw.
Prototype void ld_get_raw (l_ifc_handle iii, l_u8* const data)
Description The call copies the oldest received diagnostic frame data to the memory specified by data.
The data returned is received from SlaveResp frame.
If the receive queue is empty no data is copied.
Reference The raw and messaged-based is not differentiated outside the API A general description of the transport layer can be found in ISO 17987-2.
Table 36 defines the ld_raw_tx_status.
Table 36 — ld_raw_tx_status
Prototype l_u8 ld_raw_tx_status (l_ifc_handle iii)
Description The call returns the status of the raw frame transmission function:
Return values LD_QUEUE_EMPTY:
The transmit queue is empty In case previous calls to ld_put_raw, all frames in the queue have been transmitted.
The transmit queue contains entries, but is not full.
The transmit queue is full and cannot accept further frames.
LIN protocol errors occurred during the transfer; initialize and redo the transfer.
Reference The raw and messaged-based is not differentiated outside the API A general description of the transport layer can be found in ISO 17987-2.
Table 37 defines the ld_raw_rx_status.
Table 37 — ld_raw_rx_status
Prototype l_u8 ld_raw_rx_status (l_ifc_handle iii)
Description The call returns the status of the raw frame receive function:
Return values LD_NO_DATA:
The receive queue is empty.
The receive queue contains data that can be read.
LIN protocol errors occurred during the transfer; initialize and redo the transfer.
Reference The raw and messaged-based is not differentiated outside the API A general description of the transport layer can be found in ISO 17987-2.
Messaged-based API
Messaged-based processing of diagnostic messages manages one complete message at a time.
Table 38 defines the ld_send_message.
Prototype void ld_send_message (l_ifc_handle iii, l_u16 DataLength, l_u8 NAD, const l_u8* const data) Applicability Master and slave nodes.
The call encapsulates the information defined by data and DataLength into one or more diagnostic frames In a master node application, these frames are sent to the slave node using the NAD address, while in a slave node application, they are transmitted to the master node with the same address It is important to note that the NAD parameter is not utilized in slave nodes.
The value of the SID (or RSID) is the first byte in the data area.
DataLength is in the range of 1 to 4095 bytes The DataLength also includes the SID (or RSID) value, i.e message length plus one.
The call operates asynchronously, meaning it does not wait for the message to be sent before proceeding Additionally, the application does not alter the buffer while the calls to ld_tx_status indicate that the status is LD_IN_PROGRESS.
The data is transmitted in suitable frames (master request frame for master nodes and slave response frame for slave nodes).
If there is a message in progress, the call returns with no action.
Reference The raw and messaged-based is not differentiated outside the API A general description of the transport layer can be found in ISO 17987-2.
Table 39 defines the ld_receive_message.
Prototype void ld_receive_message (l_ifc_handle iii, l_u16* const DataLength, l_u8* const NAD, l_u8* const data) Applicability Master and slave nodes.
The call initializes the LIN diagnostic module to receive a message and store it in the designated buffer The parameter DataLength indicates the maximum permissible length for the message Upon completion of the reception, DataLength is updated to reflect the actual length of the message, and NAD is set to the NAD contained within the message.
SID (or RSID) is the first byte in the data area.
DataLength is in the range of 1 to 4 095 bytes, but never more than the value originally set in the call SID (or RSID) is included in the DataLength.
The parameter NAD is not used in slave nodes.
The call operates asynchronously, meaning it does not pause until the message is received, and the buffer remains unchanged while ld_rx_status returns LD_IN_PROGRESS If a call is initiated after the message transmission has started on the bus, the message will not be received; instead, the function will wait for the next message to begin.
The data is received from the succeeding suitable frames (master request frame for slave nodes and slave response frame for master nodes).
The application tracks the ld_rx_status and only invokes the function when the status is LD_COMPLETED; otherwise, it yields inconsistent parameter data Additionally, the distinction between raw and message-based data is not made outside the API For a comprehensive overview of the transport layer, refer to ISO 17987-2.
Table 40 defines the ld_tx_status.
Prototype l_u8 ld_tx_status (l_ifc_handle iii)
Applicability Master and slave nodes.
Description The call returns the status of the last made call to ld_send_message The following values can be returned.
Return values LD_IN_PROGRESS:
The transmission is not yet completed.
The transmission has completed successfully (and you can issue a new ld_send_message call) This value is also returned after initialization of the transport layer.
The transmission encountered an error, resulting in only partial data being sent Before processing additional messages, the transport layer is reinitialized To investigate the cause of the transmission failure, refer to the status management function l_ifc_read_status, as detailed in section 4.3.7.9.
The transmission failed because of a N_As timeout, see ISO 17987-2.
Reference The raw and messaged-based is not differentiated outside the API A general description of the transport layer can be found in ISO 17987-2.
Table 41 defines the ld_rx_status.
Prototype l_u8 ld_rx_status (l_ifc_handle iii)
Applicability Master and slave nodes.
Description The call returns the status of the last made call to ld_receive_message The following values can be returned.
Return values LD_IN_PROGRESS:
The reception is not yet completed.
The reception has been successfully completed, and all relevant information, including DataLength, NAD, and data, is now available Additionally, a new ld_receive_message call can be issued, and this value is also returned following the initialization of the transport layer.
The reception encountered an error, resulting in only partial data being received, which is deemed untrustworthy It is essential to initialize before proceeding with additional transport layer messages To investigate the cause of the reception failure, refer to the status management function l_ifc_read_status as detailed in section 4.3.7.9.
The reception failed because of an N_Cr timeout, see ISO 17987-2.
The reception failed because of an unexpected sequence number.
Reference The raw and messaged-based is not differentiated outside the API A general description of the transport layer can be found in ISO 17987-2.
Examples
Overview
Two examples are included to show how the API can be used:
The examples are not complete; there are functions that are not implemented.
Master node example
* Description : Example code for using the LI N API in a LI N master node void l_sys_irq_restore ( l_irqmask previous)
/ * Set interrupt level to previous * /
* Description : Disable the UART interrupts of the controller and
* return the interrupt level to be able to restore it
* Return value : The interrupt level before disable
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / l_irqmask l_sys_irq_disable ( void)
/ * Store the interrupt level and then disable UART interrupts * / return interrupt_level;
* Interrupt : lin_char_rx_handler
* Description : UART receive character interrupt handler for the
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / void INTERRUPT /* Compiler intrinsic */ lin_char_rx_handler ( void)
{ /* Just call the LIN API provided function to do the actual work */ l_ifc_rx_i1 ( ) ;
* Description : Main entry of application
* Return value : function never returns
/ * I nitializ e the LI N interface * / if ( l_sys_init ( ) ) {
/* The init of the LIN software failed - call error routine */
/ * I nitializ e the interface * / if ( l_ifc_init_i1 ( ) ) {
/ * I nitializ ation of the LI N interface failed - call error routine * /
/* Now is the frst time the LIN interrupts can be enabled */ l_sys_irq_restore ( INT_ENABLE_LEVEL) ;
/ * Set the normal schedule * / l_sch_set_i1 ( Normal_Schedule, 0) ;
/ * Start the OS * / start_OS ( ) ;
* Description : Main 10 ms task of the application
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / void main_application_10ms ( void)
{ /* In/output of signals Call it frst in the task to minimize j itter */
/* Do some application specifc stuff */
/* Just a small example of frame receive check and signal writing */ if ( l_fg_tst_RxInternalLightsSwitch ( ) )
/* signal reading and writing */ l_u8_wr_InternalLightsRequest ( l_u8_rd_InternalLightsSwitch( ) ) ;
Slave node example
The following example shows how a simple application in a slave is made Special focus is made on the node configuration.
* Description : Example code for using the LI N API in a LI N slave node
* The static LIN API is used ( for the core API)
* Interrupt : lin_char_rx_handler
* Description : UART receive character interrupt handler for the
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / void INTERRUPT /* Compiler intrinsic */ lin_char_rx_handler ( void)
{ /* Just call the LIN API provided function to do the actual work */ l_ifc_rx_i1 ( ) ;
* Description : Main task covering LI N functionalities
{ /* Do some application specifc stuff */
* Return value : function never returns
{ l_u8 cfg[ 20] ; l_u8 len = 0; l_bool confguration_ok = 0; l_bool stored_confguration = 0;
/ * I nitializ e the LI N interface * / if ( l_sys_init ( ) ) {
/* The init of the LIN software failed - call error routine */
/ * I nitializ e the interface * / if ( l_ifc_init_i1 ( ) ) {
/ * I nitializ ation of the LI N interface failed - call error routine * /
/* Now is the frst time the LIN interrupts can be enabled */ l_sys_irq_restore ( INT_ENABLE_LEVEL) ;
/* Confgure the communication */ confguration_ok = 0; stored_confguration = is_confguration_stored ( ) ; if ( stored_confguration) {
/* there is a stored confguration in NVRAM */ read_from_NVRAM ( cfg, &len) ;
/* confgure the communication */ ld_set_confguration ( i1, cfg, len) ; confguration_ok = 1;
/* wait for the master to confgure me for 5 s*/ l_u16 confguration_timeout = 1000; do { if ( l_ifc_read_status_i1 ( ) & SAVE_CONFIGURATION) {
/* The master node is fnished with the confguration */ confguration_ok = 1;
/* save confguration in NVRAM */ ld_read_confguration ( i1, cfg, len) ; write_to_NVRAM ( cfg, len) ;
} while ( confguration_timeout | | ! confguration_ok) ;
/* Timeout - no confguration from master, enter limp home */
/* Call the only task */ main_task ( ) ;
[1] ISO 14229-1, Road vehicles — Unified diagnostic services (UDS) — Part 1: Specification and requirements
[2] ISO 14229-2, Road vehicles — Unified diagnostic services (UDS) — Part 2: Session layer services
[3] ISO 14229-7, Road vehicles — Unified diagnostic services (UDS) — Part 7: UDS on LIN implementation
[4] ISO 15765-2, Road vehicles — Diagnostic communication over Controller Area Network (DoCAN) —
Part 2: Transport protocol and network layer services
[5] ISO 17987-2:2016, Road vehicles — Local Interconnect Network (LIN) — Part 2: Transport protocol and network layer services
[6] ISO 17987-3:2016, Road vehicles — Local Interconnect Network (LIN) — Part 2: Protocol specification
[7] ISO/IEC 7498-1, Information technology — Open Systems Interconnection — Basic Reference
Model: The Basic Model — Part 1
[8] ISO/IEC 10731, Information technology — Open Systems Interconnection — Basic Reference
Model — Conventions for the definition of OSI services