-1

我正在为跨平台桌面应用程序工作。我使用 Qt 在 C++ 中开发它,并且已经通过套接字( QTcpSocket )实现了 PC 端 Omron FINS TCP 协议驱动程序。当我通过 FINS 协议从寄存器读取时 - 我在 30 毫秒内收到正确的响应,但是当我写入 plc 的寄存器时 - plc 没有响应 - 套接字超时错误( QAbstractSocket 错误代码 = 5 )。

从寄存器读取代码(函数接收 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 value); -->

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;
}

其中 f - 是一些临时日志文件指针 sc - 发送/接收 FINS 命令的 QTcpSocket 实例 PLC: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
}

当我使用 Multiway 软件测试命令时 - 收到响应并将值放入 register ,但与 QTcpSocket 和错误相同,为什么?我的问题是:您在运行 FINS 驱动程序时是否出现过这样的问题?为什么在FINS write to register命令形成ok时会出现无响应的情况?如果是,如何克服/修复?

4

1 回答 1

1

我在几个工业项目中创建并使用了这个库,所以它很稳定。但缺乏文档。 https://bitbucket.org/vladimirek/omronlib

于 2013-05-30T19:17:55.970 回答