LIN 2.0

LIN 2.0 통신 프로그래밍 강좌 6 - 진단과 설정 구현 2

BLDC 2013. 3. 7. 16:28

<마스터 요청 종류> 

 

SuID : supplier Id, 공급자 아이디        MID : message Id, 메시지 프레임 아이디

FID : function Id, 기능 아이디             LSB : Least significant byte

MSB : Most significant byte

 

  • 프레임 아이디 할당 (의무 구현)

본 강좌의 메시지 프레임은 COMMAND_MSG(MID=1)와 STATE_MSG(MID=2) 2개 이므로 이에 대한 PID 할당만을 처리하고 긍정 응답을 준비한다. 긍정 응답은 아래 표와 같이 LIN 진단과 설정 2.5.1절 표2.5에 규정되어 있다. 만일 자신의 노드에 없는 MID이거나 SuID(공급자 아이디)가 틀릴 경우에는 응답을 하지말아야한다.(LIN 진단과 설정 규정 2.5.1절에 긍정 응답만이 규정되어 있으며, 이의 구현은 선택적이므로 응답하지 않아도 무방하다.) 

 

표2.5: 프레임 ID 할당에 대한 긍정 응답

 

if (mrPCI == 0x06 && mrSID == 0xB1)    // 프레임 아이디 할당 요청

{

mrSuID = mrD1 + (mrD2 << 8);

mrMID = mrD3 + (mrD4 << 8);

if (mrSuID == mySuID &&  (mrMID == 1 || mrMID == 2))

{

messageTable[mrMID].PID = mrD5;    // PID 할당

messageTable[mrMID].valid = 1;

 

// 긍정 응답 준비

SLAVE_RES.data[] = {myNAD, 0x01, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

mustSlaveResponse = 1;

}

else    // SuID 다르거나 MID 목록에 없음.

{

// 프레임 아이디 할당에 대한 부정 응답은 없음.

// LIN 진단과 설정 2.5.1절 참조

mustSlaveResponse = 0;

}

}

------------------------------------------------------------------------------------------------

  • 아이디로 읽기 (의무 구현)

아이디로 읽기는 마스터가 슬레이브의 LIN 제품 아이디, 일련번호, 메시지 아이디 등 여러가지 정보를 취득하기 위한 요청이다. 슬레이브는 마스터가 지정한 ID(D1)에 해당하는 정보(LIN 진단과 설정 규정 표2.8)를 긍정응답으로 전송해야하며, 본 강좌에는 메시지가 단 2개이므로 다음의 표에 해당되는 것 만 긍정응답하면 된다. LIN 진단과 설정 규정 2.5.2절 노트를 보면 아래 표에서도 id=0일 때의 응답만이 의무적으로 구현해하고, 나머지는 선택적이므로 구현하지 않아도 된다. 본 강좌에서는 모두 구현하기로 한다.

 

 

만일 마스터가 슬레이브에게 없는 정보를 요청하면 슬레이브는 LIN 진단과 설정 규정 표2.9의 부정응답을 전송해야한다.

 

 

else if (mrPCI == 0x06 && mrSID == 0xB2)    // 아이디로 읽기 요청

{

mrSuID = mrD2 + (mrD3 << 8);

mrFID = mrD4 + (mrD5 << 8);

if (mrSuID == mySuID &&  mrFID == myFID)

{

mustSlaveResponse = 1;

switch(mrD1)    // mrD1 : 마스터가 지정한 표2.8의 아이디

{

case 0:    // 아이디 요청

SLAVE_RES.data[] = {myNAD, 0x06, 0xF2, mySuID,

mySuID>>8, myFID, myFID>>8, myVID};

break;

 

case 1:    //일련번호 요청

SLAVE_RES.data[] = {myNAD, 0x05, 0xF2,

mySerial, mySerial>>8, mySerial>>16,

mySerial>>24, 0xFF};

break;

case 16:    //MID(COMMAND_MSG) 요청

SLAVE_RES.data[] = {myNAD, 0x04, 0xF2,

COMMAND_MSG.MID, COMMAND_MSG.MID>>8, COMMAND_MSG.PID, 0xFF, 0xFF};

break;

case 17:    //MID(STATE_MSG) 요청

SLAVE_RES.data[] = {myNAD, 0x04, 0xF2,

STATE_MSG.MID,

STATE_MSG.MID>>8, STATE_MSG.PID, 0xFF, 0xFF};

break;

default :    // 부정응답

SLAVE_RES.data[] = {myNAD, 0x03, 0x7F, 0xB2,

0x12, 0xFF, 0xFF, 0xFF};

break;

}

}

else

{

// 공급자 아이디 또는 기능 아이디가 다를 경우, 응답하지않는다.

mustSlaveResponse = 0;

}

}

------------------------------------------------------------------------------------------------

 

  • NAD 할당 (옵션)

클러스터의 슬레이브 노드들이 같은 NAD를 사용하고 있다면 충돌이 발생할 수 있다. LIN 제품을 생한하는 제조사는 원래 LIN 조합에 가입하여 고유한 제조사 아이디를 부여받아야하므로 NAD가 중복되더라도 마스터는 제조사 아이디로 구분할 수 있다. 조합에 가입하지 않은 제조사는 클러스터 또는 마스터 제조사로부터 제조사 아이디를 부여받아야한다. 어떤 경우든 제조사 아이디만 할당받고 NAD를 제조사에서 임의로 부여한다면 NAD가 중복될 수 있다. NAD할당 요청은 NAD가 중복된 상황에서 특정한(제조사 아이디로 지정한) 노드의 NAD를 변경하는 기능이다.

NAD 할당 요청을 수신한 노드는 공급자 및 기능 아이디가 자신의 것이라면 NAD를 변경하고, 긍정 응답을 해야한다. 만일 공급자 또는 기능 아이디가 다를 경우에는 다른 노드가 응답해야하는 경우이므로 부정 응답을 하는 대신 슬레이브 응답을 아예 전송하지 말아야한다. 따라서 이 경우는 아래와 같은 긍정 응답만이 존재한다.

 

참고로 NAD 할당의 응답은 의무가 아니라 옵션이므로 구현하지 않아도 무방하다. 주의할 것은 긍정 응답의 NAD는 할당된 새 NAD가 아니라 변경 이전의 NAD로 응답해야한다는 점이다.

 

else if (mrPCI == 0x06 && mrSID == 0xB0)    // NAD 할당 요청

{

mrSuID = mrD1 + (mrD2 << 8);

mrFID = mrD3 + (mrD4 << 8);

if (mrSuID == mySuID &&  mrFID == myFID)

{

mustSlaveResponse = 1;

 

SLAVE_RES.data[] = {myNAD, 0x01, 0xF0, 0xFF, 0xFF,

        0xFF, 0xFF, 0xFF};

 

// 응답 준비 후 NAD 변경

myNAD = mrD5;    // mrD5 = new NAD

}

else

{

// 공급자 아이디 또는 기능 아이디가 다를 경우, 응답하지않는다.

mustSlaveResponse = 0;

}

}

------------------------------------------------------------------------------------------------

 

  • 조건부 NAD 변경 (옵션)

조건부 NAD 변경은 아래와 같이 규정에서 제시한 순서에 따라 수행하면 된다.

  1. 표2.8에서 Id로 지정된 ID를 얻는다.
  2. Byte로 지정한 데이터 바이트를 추출한다.(Byte=1은 첫 번째 바이트 D1에 해당한다.)
  3. Invert와 비트별 XOR 연산
  4. Mask와 비트별 AND 연산
  5. 최종 결과가 0이면 NAD를 New NAD로 변경한다.
응답의 구현은 옵션이지만 만일 NAD가 변경되었다면 긍정 응답을 전송하는 것이 바람직하다. 만일 최종 결과가 0이 아니면 중복된 NAD를 갖는 다른 노드에서 응답할 긍정 응답을 전송할 수 있으므로 자신은 응답하지 말아야한다.

 

 

else if (mrPCI == 0x06 && mrSID == 0xB3)    // 조건부 NAD 변경 요청

{

// 긍정응답을 해야한다고 가정하고, 응답하지 말아야하는 경우만 걸러낸다.

mustSlaveResponse = 1;

 

switch(mrD1)    // mrD1 : Id

{

case 0:

switch(mrD2)    // mrD2 : byte

{

case 1 : temp = mySuID;         break;

case 2 : temp = mySuID>>8;    break;

case 3 : temp = myFID;         break;

case 4 : temp = myFID>>8;    break;

case 5 : temp = myVID;         break;

}

break;

case 1:

switch(mrD2)    // mrD2 : byte

{

case 1 : temp = mySerial;         break;

case 2 : temp = mySerial>>8;    break;

case 3 : temp = mySerial>>16;   break;

case 4 : temp = mySerial>>24;   break;

case 5 : temp = 0xFF;               break;

}

break;

case 16:

switch(mrD2)    // mrD2 : byte

{

case 1 : temp = COMMAND_MSG.MID;        break;

case 2 : temp = COMMAND_MSG.MID>>8;   break;

case 3 : temp = COMMAND_MSG.PID;         break;

case 4 : temp = 0xFF;                                 break;

case 5 : temp = 0xFF;                                 break;

}

break;

case 17:

switch(mrD2)    // mrD2 : byte

{

case 1 : temp = STATE_MSG.MID;        break;

case 2 : temp = STATE_MSG.MID>>8;   break;

case 3 : temp = STATE_MSG.PID;         break;

case 4 : temp = 0xFF;                          break;

case 5 : temp = 0xFF;                          break;

}

break;

default:    // 표2.8에 해당 없는 경우 응답하지않는다.

mustSlaveResponse = 0;

break;

}

if (mustSlaveResponse)

{

temp ^= mrD4;    // XOR 연산

temp &= mrD3;    // mrD3:Mask, AND 연산

 

if (temp == 0)    // 연산결과가 0이면 응답준비 후 NAD 변경

{

SLAVE_RES.data[] = {myNAD, 0x01, 0xF3, 0xFF, 0xFF,

        0xFF, 0xFF, 0xFF};

myNAD = mrD5;    // mrD5 : new NAD

}

else

{

// 연산결과가 0이 아니면 응답하지 않는다.

mustSlaveResponse = 0;

}

}

}

------------------------------------------------------------------------------------------------