2011-10-24 13 views
-1

저는 크로스 플랫폼 데스크탑 응용 프로그램에서 작업 중입니다. Qt를 사용하여 C++로 개발했으며 소켓을 통해 PC 측 Omron FINS TCP 프로토콜 드라이버를 이미 구현했습니다. (QTcpSocket). FINS 프로토콜을 통해 레지스터에서 읽을 때 - 30ms 내에 올바른 응답을 수신하지만 plc의 레지스터에 쓸 때 - plc-socket timeout 오류 (QAbstractSocket 오류 코드 = 5)의 응답이 없습니다.Qt를 사용하여 PC 측에서 Omron FINS 프로토콜 구현 (C++) [Driver]

레지스터에서 읽는 코드 (함수는 reg_addr - 레지스터의 주소 및 값 업데이트) : bool fins_read_reg (int reg_addr, int * value); ->

static unsigned char fins_cmnd[MAX_MSG], fins_resp[MAX_MSG],fins_tcp_header[MAX_HEADER]; 
static unsigned char fins_send_frame[34], fins_receive_frame[32]; 
static int sendlen, recvlen; 
//char sid = 0; 
if(sid > 0xFF) 
    sid = 0; 
if(f!=0) 
{ 

    fprintf(f,"BEGIN TO READ \n"); 
    fprintf(f," reg_addr = %d \n",reg_addr); 
    fprintf(f," value = %d \n",*value); 

} 
/* SEND FINS/TCP COMMAND*/ 
/* 
* GENERATE FINS COMMAND FRAME 
*/ 
fins_send_frame[0] = 'F'; /* Header */ 
fins_send_frame[1] = 'I'; 
fins_send_frame[2] = 'N'; 
fins_send_frame[3] = 'S'; 
fins_send_frame[4] = 0x00; /* Length */ 
fins_send_frame[5] = 0x00; 
fins_send_frame[6] = 0x00; 
fins_send_frame[7] = 18+8; /*Length of data from Command up to end of FINS frame */ 
fins_send_frame[8] = 0x00; /* Command */ 
fins_send_frame[9] = 0x00; 
fins_send_frame[10] = 0x00; 
fins_send_frame[11] = 0x02; 
fins_send_frame[12] = 0x00; /* Error Code */ 
fins_send_frame[13] = 0x00; 
fins_send_frame[14] = 0x00; 
fins_send_frame[15] = 0x00; 
//command: 
fins_send_frame[16] = 0x80; /* ICF */ //put 0x00 - response required //was 0x80 
fins_send_frame[17] = 0x00; /* RSV */ 
fins_send_frame[18] = 0x03; /* GCT */ 
fins_send_frame[19] = 0x00; /* DNA */ 
fins_send_frame[20] = srv_node_no; /* DA1 *//* Ethernet Unit FINS NODE NUMBER*/ 
fins_send_frame[21] = 0x00; /* DA2 */ 
fins_send_frame[22] = 0x00; /* SNA */ 
fins_send_frame[23] = cli_node_no; /* SA1 *//* WS FINS NODE NUMBER OBTAINED 
AUTOMATICALLY*/ 
fins_send_frame[24] = 0x00; /* SA2 */ 
fins_send_frame[25] = sid; //++sid; /* SID */ 
fins_send_frame[26] = 0x01; /* MRC */ //1 
fins_send_frame[27] = 0x01; /* SRC */ //read 
// change to read: 
fins_send_frame[28] = memory_area_designation_code(reg_addr); /* VARIABLE TYPE: DM*/ 
if(f!=0) 
{ 
    fprintf(f,"FINS/TCP memory area designation code = %d \n",fins_cmnd[28]); 
} 
if(memory_area_designation_code(reg_addr) == 0xB0) //-0x0c000 
{ 
fins_send_frame[29] = (unsigned char)((reg_addr-0x0C000)>>8);  
fins_send_frame[30] = (unsigned char)((reg_addr-0x0C000)&0xFF); //low register 
if(f!=0) 
{ 
fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); 
fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); 
} 


} 
if(memory_area_designation_code(reg_addr) == 0xB1) //-0x0DE00 
{ 
    fins_send_frame[29] = (unsigned char)((reg_addr-0x0DE00)>>8); 
    fins_send_frame[30] = (unsigned char)((reg_addr-0x0DE00)&0xFF); 
    if(f!=0) 
    { 
    fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); 

    fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); 
    } 
} 
if(memory_area_designation_code(reg_addr) == 0x82) //-0x10000 
{ 
    fins_send_frame[29] = (unsigned char)((reg_addr-0x10000)>>8); 
    fins_send_frame[30] = (unsigned char)((reg_addr-0x10000)&0xFF); 
    if(f!=0) 
    { 
    fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); 

    fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); 
    } 
} 
if(memory_area_designation_code(reg_addr) == 0xB3) //-0x0BA00 
{ 
    fins_send_frame[29] = (unsigned char)((reg_addr-0x0BA00)>>8); 
    fins_send_frame[30] = (unsigned char)((reg_addr-0x0BA00)&0xFF); 
    if(f!=0) 
    { 
    fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); 

    fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); 
    } 
} 
fins_send_frame[31] = 0x00;//bit number 
//number of words to read: 
fins_send_frame[32] = 0x00; /* WORDS READ: 1*/ 
fins_send_frame[33] = 0x01; 
/* SEND FINS/TCP COMMAND*/ 
sendlen = 34; 
sc.write((const char*)fins_send_frame,sendlen); 
if(sc.waitForBytesWritten(RESP_TIMEOUT)) 
{ 

} 
else 
{ 
    if(f!=0) 
    { 
     fprintf(f,"2.error in sending FINS send frame of command %d \n",sc.error()); 
    } 
    return false; 
} 
//lets try to get response here 
if(sc.waitForReadyRead(RESP_TIMEOUT)) 
{ 
    if(f!=0) 
    { 
     fprintf(f,"2.received %d \n",recvlen = sc.bytesAvailable()); 
    } 
    sc.read((char*)fins_receive_frame,recvlen); 
    //print received header: 
    if(f!=0) 
    { 

    for(int i =0;i<recvlen;i++) 
    { 

    } 
    } 
    //check for errors: 
    if(((int)fins_receive_frame[28] == 0) && ((int)fins_receive_frame[29] == 0)) 
    { 
     //command sent ok 
     sid++; 
     //lets get value: 
     *value = (int)((0x0000|fins_receive_frame[30])<<8) + (int) 

     (0x00FF&fins_receive_frame[31]); 

     if(f!=0) 
     { 
      //lets get value: 
      fprintf(f,"2.* value = %d \n",value); 

     } 
      return true; 
    } 
    else 
    { 
     //there were errors when sending 
     *value = 0; 
     if(f!=0) 
     { 
      //lets get value: 
      fprintf(f,"fields 28 and 29 are not null \n"); 
     } 
     return false; 
    } 
} 
else 
{ 
    //can't get response - error: 
    //no response: 
      if(f!=0) 
      { 
       fprintf(f,"2.no response %d \n",sc.error()); 
      } 
      return true; 
} 




*** 
Code snippet of writing to register (function receives reg_addr - address of a register and value to put to that register): 


BOOL fins_write_reg (INT의 reg_addr, CONST INT의 값); ->

f는
static unsigned char fins_cmnd[MAX_MSG], fins_resp[MAX_MSG],fins_tcp_header[MAX_HEADER]; 
static unsigned char fins_send_frame[36], fins_receive_frame[30]; 
static unsigned char srv_node_no, cli_node_no; 
static int sendlen, recvlen; 
// char sid = 0; 
if(sid > 0xFF) 
    sid = 0; 

if(f!=0) 
{ 
    fprintf(f,"BEGIN TO WRITE \n"); 
    fprintf(f," reg_addr = %d \n",reg_addr); 
    fprintf(f," value = %d \n",value); 
} 
/* SEND FINS/TCP COMMAND*/ 
/* 
* GENERATE FINS COMMAND FRAME 
*/ 
//fins header body 
fins_send_frame[0] = 'F'; /* Header */ 
fins_send_frame[1] = 'I'; 
fins_send_frame[2] = 'N'; 
fins_send_frame[3] = 'S'; 
fins_send_frame[4] = 0x00; /* Length */ 
fins_send_frame[5] = 0x00; 
fins_send_frame[6] = 0x00; 
fins_send_frame[7] = 0x1C; //20+8; 
fins_send_frame[8] = 0x00; /* Command */ 
fins_send_frame[9] = 0x00; 
fins_send_frame[10] = 0x00; 
fins_send_frame[11] = 0x02; 
fins_send_frame[12] = 0x00; /* Error Code */ 
fins_send_frame[13] = 0x00; 
fins_send_frame[14] = 0x00; 
fins_send_frame[15] = 0x00; 
//fins command body 
fins_send_frame[16] = 0x80; /* ICF */ 
fins_send_frame[17] = 0x00; /* RSV */ 
fins_send_frame[18] = 0x02; /* GCT */ 
fins_send_frame[19] = 0x00; /* DNA */ 
fins_send_frame[20] = srv_node_no; /* DA1 *//* Ethernet Unit FINS NODE NUMBER*/ 
fins_send_frame[21] = 0x00; /* DA2 */ 
fins_send_frame[22] = 0x00; /* SNA */ 
fins_send_frame[23] = cli_node_no; /* SA1 *//* WS FINS NODE NUMBER 
AUTOMATICALLY*/ 
fins_send_frame[24] = 0x00; /* SA2 */ 
fins_send_frame[25] = sid; /* SID */ 
fins_send_frame[26] = 0x01; /* MRC */ //1 
fins_send_frame[27] = 0x02; /* SRC */ //1 - write 
// change to write: 
fins_send_frame[28] = memory_area_designation_code(reg_addr); /* VARIABLE TYPE: DM*/ 
if(f!=0) 
{ 

} 
if(memory_area_designation_code(reg_addr) == 0xB0) //-0x0c000 
{ 
fins_send_frame[29] = (unsigned char)((reg_addr - 0x0c000)>>8);  
fins_send_frame[30] = (unsigned char)((reg_addr - 0x0c000)&0xFF); 
if(f!=0) 
{ 
fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); 
fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); 
} 
} 
if(memory_area_designation_code(reg_addr) == 0xB1) //-0x0DE00 
{ 
    fins_send_frame[29] = (unsigned char)((reg_addr - 0x0DE00)>>8); 
    fins_send_frame[30] = (unsigned char)((reg_addr - 0x0DE00)&0xFF); 
    if(f!=0) 
    { 
    fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); 
    fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); 
    } 
} 
if(memory_area_designation_code(reg_addr) == 0x82) //-0x10000 
{ 
    fins_send_frame[29] = (unsigned char)((reg_addr - 0x10000)>>8); 
    fins_send_frame[30] = (unsigned char)((reg_addr - 0x10000)&0xFF); 
    if(f!=0) 
    { 
    fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); 
    fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); 
    } 
} 
if(memory_area_designation_code(reg_addr) == 0xB3) //-0x0BA00 
{ 
    fins_send_frame[29] = (unsigned char)((reg_addr - 0x0BA00)>>8); 
    fins_send_frame[30] = (unsigned char)((reg_addr - 0x0BA00)&0xFF); 
    if(f!=0) 
    { 
    fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); 
    fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); 
    } 
} 
fins_send_frame[31] = 0x00;//bit number 
//number of words to read: 
fins_send_frame[32] = 0x00; /* number of data words */ 
fins_send_frame[33] = 0x01; 
//putting actual write value: 
fins_send_frame[34] = (unsigned char)(value >> 8); //high byte 
fins_send_frame[35] = (unsigned char)(value&0xFF); //low byte 
//displaying what is written: 
if(f!=0) 
{ 
fprintf(f,"fins_send_frame[34] = %d \n",fins_send_frame[34]); 
fprintf(f,"fins_send_frame[35] = %d \n",fins_send_frame[35]); 
} 
sendlen = 36; 
/* SEND FINS/TCP COMMAND*/ 
sc.write((const char*)fins_send_frame,sendlen); 
if(sc.waitForBytesWritten(RESP_TIMEOUT)) 
{ 
    if(f!=0) 
    { 

    } 
} 
else 
{ 
    if(f!=0) 
    { 
     fprintf(f,"2.error in sending FINS tcp send frame of command %d \n",sc.error()); 
    } 
    return false; 
} 
//sc.flush(); 
//lets try to get response here : 
if(sc.waitForReadyRead(RESP_TIMEOUT)) // here it is RESPONSE TIMEOUT ERROR 
{ 
    if(f!=0) 
    { 
     fprintf(f,"2.received %d \n",recvlen = sc.bytesAvailable()); 
    } 
    sc.read((char*)fins_receive_frame,recvlen); 
    if(f!=0) 
    { 
    for(int i =0;i<recvlen;i++) 
    { 
     fprintf(f,"2.received fins_receive_frame[%d] = %d \n",i,fins_receive_frame[i]); 
    } 
    } 
    //basic check - no error 
    if(((int)fins_receive_frame[28] == 0) && ((int)fins_receive_frame[29] == 0)) 
    { 
     //command sent ok 
     sid++; 
     if(f!=0) 
     { 
      fprintf(f,"receive response does not contain errors"); 
     } 
      return true; 
    } 
    else 
    { 
     //there were errors when sending 
     if(f!=0) 
     { 
      fprintf(f,"receive response contains errors"); 
     } 
     return false; 
    } 
} 
else //cannot receive response 
{ 
    if(f!=0) 
    { 
    fprintf(f,"3.no response %d \n",sc.error()); 
    }  
    return true; 
} 

- 일부 임시 로그 파일 포인터 SC입니다 - /가 FINS는 PLC 명령을 수신 보내 QTcpSocket 인스턴스 : CP1L - L14DT1-D 이더넷 옵션 보드 : CP1W- CIF41

메모리 영역 지정 코드 기능 :

int FinsOverEthCP::memory_area_designation_code(const int addr) 
{ 
// area codes 
if(addr>0x0BFFF&&addr<0x0D800) //B0 , CIO area 
    return 0xB0; 
if(addr>0x0DDFF&&addr<0xE000) //work area 
    return 0xB1; //TODO: clarified code , from memory area designation codes table 
if(addr>0xFFFF&&addr<0x18000) //DM area 
    return 0x82; 
if(addr>0xB9FF&&addr<0xBC00) //A448 - A959 
    return 0xB3; 
else 
    return 0x80; //CIO,LR,HR,AR area 
} 

W 암탉 나는 Multiway 소프트웨어를 사용하여 명령을 테스트했습니다. 응답은 수신되었고 값은 등록하도록 putted되었지만 QTcpSocket과 오류는 동일합니다. 이유는 무엇입니까? 내 질문 : FINS 드라이버를 실행할 때 이러한 문제가 발생 했습니까? FINS 쓰기 명령이 등록 명령 인 동안 응답 상황이 될 수없는 이유는 무엇입니까? 그렇다면 극복/수정 방법은 무엇입니까?

답변