LIN은 overload를 막기 위해 schedule table을 통해 모든 통신을 진행합니다. 이 table이 어떤 것인지 차근차근 알아봅시다.
Time base
한 Frame에는 Header와 Response가 있고 최대 8-byte 통신이 가능하다고 했습니다. 한 Frame 통신당 transfer에 걸리는 시간이 정해져 있는데, time base를 기반으로 정해집니다.
한 Frame이 진행되는 시간은 time base의 n 배이고, 통상적으로 time base는 5ms 또는 10ms입니다. 그러니까 LIN이 굉~~장히 느리다는 거죠. 이전 글에서도 설명해 드렸지만 최대 통신속도가 20kbps이고, 이는 통상적으로 UART baud rate로 사용하는 38400보다 느립니다;;
또한 이전 글에서 PID를 통해 모든 통신을 제어한다고 했는데요, 이 PID는 LDF 파일을 통해 사전에 정의됩니다. 그러니까 이 LDF파일을 기반으로 API를 짜고 이를 통해 controller를 제어하는 겁니다.
LDF format
그러면 통신을 제어하는 table 파일이 어떻게 구성되어 있는지 알아봅시다.
<LIN_description_file> ::=
LIN_description_file ;
<LIN_protocol_version_def>
<LIN_language_version_def>
<LIN_speed_def>
(<Channel_name_def>)
<Node_def>
(<Node_composition_def>)
<Signal_def>
(<Diag_signal_def>)
<Frame_def>
(<Sporadic_frame_def>)
(<Event_triggered_frame_def>)
(<Diag_frame_def>)
<Node_attributes_def>
<Schedule_table_def>
(<Signal_groups_def>)
(<Signal_encoding_type_def>)
(<Signal_representation_def>)LDF 파일은 기본적으로 protocol 버전과 Node 정보, signal과 Frame, 마지막으로 실제 통신이 진행되는 순서인 Schedule table로 구성됩니다. 그럼, 하나씩 자세히 분석해 봅시다.
Global definition
<LIN_protocol_version_def> ::=
LIN_protocol_version = char_string ;
<LIN_language_version_def> ::=
LIN_language_version = char_string ;
<LIN_speed_def> ::=
LIN_speed = real_or_integer kbps ;
<Channel_name_def> ::=
Channel_name = identifier ;Global definition에서는 protocol의 버전과 통신속도, 그리고 채널 이름을 정합니다.
LIN_description_file;
LIN_protocol_version = "2.2";
LIN_language_version = "2.2";
LIN_speed = 19.2 kbps;
Channel_neme = "DB";위의 예시를 보면, protocol 2.2 version을 사용하고 있고, 통신 속도는 19.2kbps(이게 통상적으로 많이 사용하는 통신 속도라고 보시면 되겠습니다.)이고, DB라고 명명한 것을 알 수 있습니다.
Node definition
<node_def> ::=
Nodes {
Master: <node_name>, <time_base> ms, <jitter> ms ;
Slaves: <node_name>([, <node_name>]) ;
}다음으로 Node를 정의하는데요, 여기서 통신에 참여하는 Master와 Slave 들이 정해집니다.
Nodes {
Master: CEM, 5ms, 0.1ms;
Slaves: LSM, RSM;
}위의 예시에는 Master가 CEM이고 Slave로 LSM/RSM 두 개를 사용하네요. Time base가 5ms이므로 한 Frame 당 5, 10, 15, 20… ms가 걸릴 것으로 예상됩니다.
<node_attributes_def> ::=
Node_attributes {
[<node_name> {
LIN_protocol = <protocol_version> ;
configured_NAD = <diag_address> ;
(initial_NAD = <diag_address> ;)
<attributes_def> ;
}]
}
<attributes_def> ::=
product_id = <supplier_id>, <function_id> (, <variant>) ;
response_error = <signal_name> ;
(fault_state_signals = <signal_name>([, <signal_name>]) ;)
(P2_min = real_or_interger ms ;)
(ST_min = real_or_interger ms ;)
(N_As_timeout = real_or_integer ms ;)
(N_Cr_timeout = real_or_integer ms ;)
<configurable_frames_20_def> | <configurable_frames_21_def>Node attribute를 통해 상세한 정보를 기술합니다. 특히, product_id는 Diagnostic frame(PID: 0x3C or 0x3D)에 필요합니다.
Node_attributes {
RSM {
LIN_protocol = "2.0";
configured_NAD = 0x20;
product_id = 0x4E4E, 0x4553, 1;
response_error = RSMerror;
P2_min = 150 ms;
ST_min = 50 ms;
configurable_frames {
Node_Status_Event = 0x000; CEM_Frm1 = 0x0001; RSM_Frm1 = 0x0002;
RSM_Frm2 = 0x0003;
}
}Slave 중 하나인 RSM의 Node attributes 정의 예시입니다.
Signal definition
<signal_def> ::=
Signals {
[<signal_name>: <signal_size>, <init_value>, <published_by>
[, <subscribed_by>] ;]
}통신에 사용되는 모든 Signal이 정의되는데요, 여기서 master_tx/rx가 정해집니다. 이거 못 찾아서 세미나에서 엄청 혼났어요;;
Signals {
InternalLightsRequest: 2, 0, CEM, LSM, RSM;
RightIntLightsSwitch: 8, 0, RSM, CEM;
LeftIntLightsSwitch: 8, 0, LSM, CEM;
LSMerror: 1, 0, LSM, CEM;
RSMerror: 1, 0, RSM, CEM;
IntTest: 2, 0, LSM, CEM;
}InternalLightsRequest라는 signal은 CEM이 LSM, RSM에게 2-byte의 data를 transfer 한다는 의미입니다, 그러니까 master_tx 신호인 거죠. RightIntLightsSwitch signal은 slave인 RSM이 master인 CEM에게 8-byte data를 보내는, master_rx 신호라고 이해하시면 되겠습니다.
Frame definition
<frame_def> ::=
Frames {
[<frame_name>: <frame_id>, <published_by>, <frame_size> {
[<signal_name>, <signal_offset> ;]
}]
}LIN 통신에 사용되는 Frame은 일반적으로 데이터를 송수신하는 unconditional frame 이외에 node 정보를 주고받는 diagnostic frame 등등 여러 frame 들이 있습니다. LDF의 frame definition을 통해 모든 frame을 정의합니다.
Frames {
CEM_Frm1: 0x01, CEM, 1 {
InternalLightsRequest, 0;
}
LSM_Frm1: 0x02, LSM, 2 {
LeftIntLightsSwitch, 8;
}
}여기서 PID가 나오는군요, 그리고 다시 한번 frame publisher를 알려줍니다.
Schedule table
<schedule_table_def> ::=
Schedule_tables {
[<schedule_table_name> {
[<command> delay <frame_time> ms ;]
}]
}이제 마지막인데요, schedule table을 통해 frame의 순서와 통신하는 데 걸리는 시간이 정해집니다.
schedule_tables {
VL1_ST1 {
VL1_CEM_Frm1 delay 15 ms;
VL1_LSM_Frm1 delay 15 ms;
VL1_CPM_Frm1 delay 15 ms;
VL1_CPM_Frm1 delay 20 ms;
}
}위의 예시에는 4개의 Frame이 나오고 각각 15, 15, 15, 20ms delay로 정의됩니다. 그런데 이 delay가 무엇을 의미할까요? 실제 통신을 살펴보자면,
Delay는 Frame 사이의 간격이 아니라 실제 Frame 통신이 걸리는 시간을 의미함을 알 수 있습니다. 그래서 앞에서 설정한 time delay인 5ms의 n 배인 것을 알 수 있습니다.
여기까지 LDF 포맷과 예시를 살펴보았는데요, 굉장히 간단하게 설명해 드렸으니 꼭 specification 문서를 확인하셔야 합니다!!