of the truck right here and calculate the frame slot time
for a 9600 bps LIN link. Here are the mathematical
knowns:
There are 34 bits in the frame header.
Start Bit 01
12 zero bits 12
Stop Bit 01
Start Bit 01
Auto-Baud Chirp 08
Stop Bit 01
Start Bit 01
Protected Identifier 08
Stop Bit 01
Total Bits
34
T 9600 bps = 1/9600 = 104 µs
BIT
(N + 1) = 9 (maximum number of data bytes
DATA
in a frame + checksum byte)
Here are the frame slot equations:
T = 34 T
HEADER_NOMINAL BIT
= 03.54 ms
T = 10 (N + 1) T
RESPONSE_NOMILAL DATA BIT
= 10.42 ms
T = T +
FRAME_NOMINAL HEADER_NOMINAL
T = 13.96 ms
RESPONSE_NOMILAL
T = 1.4 T
HEADER_MAXIMUM HEADER_NOMINAL
= 04.96 ms
T = 1.4 T
RESPONSE_MAXIMUM RESPONSE_NOMILAL
= 14.58 ms
T = T +
FRAME_MAXIMUM HEADER_MAXIMUM
T = 19.54 ms
RESPONSE_MAXIMUM
Rounding up, the frame slot numbers tell us that we
can set the frame slot time between 14.0 and 20.0 ms.
A safe bet on the minimum side would be 17.0 ms, which
will still be a bit high for frames that don’t carry the full
load of eight data bytes. We could get really persnickety
about all of the frame slot stuff and implement what the
LIN Specification calls a schedule table which defines a
unique frame slot for every frame that will be published by
the master and slave nodes.
Routing the frame involves yet another LIN element
called the message identifier. The message identifier is
a 16-bit message number that is associated with a
protected identifier. A protected identifier is simply an
identifier along with its pair of parity bits in the most
significant bit positions. A LIN slave node that adheres to
the recommendations of the LIN Specification stores
message identifiers in ROM and their associated protected
identifiers in SRAM.
Data within a frame is categorized as signals or
44 SERVO 07.2009
diagnostic messages. Signals are no more than arrays of
one to eight bytes or a scalar value. For instance, a
Boolean signal is a one-bit scalar while a 16-bit signal is
treated as an unsigned integer. A signal is always located
in the same position in the frame relative to a specific
identifier. Diagnostic messages are found within frames
with two reserved identifiers (decimal 60 and 61). The
data within a diagnostic message determines how the
message is interpreted. Slave tasks publish (place a
response on the bus) and subscribe to (receive and act
upon) the diagnostic message according to their current
state and programming. Master request frames (identifier
= 60) and slave response frames (identifier = 61) are
examples of diagnostic frames.
At this point, we could continue this LIN standards
discussion all the way through the contents of diagnostic
frames and how each data field within a diagnostic frame is
defined and used. For example, standardized LIN nodes
must include manufacturer information called a function ID
in addition to a LIN Consortium assigned supplier ID.
However, we’re not here to design LIN standard ECUs
(electronic control units) for automobiles. So, we can
bypass the supplier ID requirement and choose only the
LIN disciplines we wish to include into our robotic LIN
driver. Let’s begin our LIN coding work by improving upon
the transmit code we wrote last time.
Updated LIN TX Driver
The first byte sent in a master published LIN frame
is the Auto-Baud chirp (0x55). After subscribing to the
chirp, slave units on the bus wait for the protected
identifier byte (PID) which is the identifier merged with
its pair of parity bytes. Thus, the very first action that
our send_lin_frame function must take is to calculate the
PID using the supplied identifier. Before we fire off the
send_lin_frame function, let’s place a call to a function
called load_ 8 which assembles the maximum number
of bytes a LIN frame can legally handle into an array
called lin_buf:
void load_8(char id_lin,char data1,char
data2,char data3,char data4,char data5,char
data6,char data7,char data8)
{
lin_buf[msg_len]
lin_buf[id_loc]
lin_buf[msg_loc]
lin_buf[msg_loc+1]
lin_buf[msg_loc+2]
lin_buf[msg_loc+3]
lin_buf[msg_loc+4]
lin_buf[msg_loc+5]
lin_buf[msg_loc+6]
lin_buf[msg_loc+7]
chksum_loc
= 8;
= id_lin;
= data1;
= data2;
= data3;
= data4;
= data5;
= data6;
= data7;
= data8;
= msg_loc + 8;
}