Как я могу добавить код в тестовую программу libnodave (testISO_TCP упрощенный), который защищает процедуру чтения от сбоев? - PullRequest
2 голосов
/ 13 августа 2011

Я начну с того, что я студент колледжа с небольшим опытом работы с ++.Сколько раз вы слышали это правильно?Я работаю с тестовой программой testISO_TCP (упрощенная версия) из библиотеки libnodave.Эта программа выполняет простое считывание значений флага и блоков данных, когда она подключена к ПЛК Seimens 300.Программа сама по себе не выдает никаких ошибок.Надеюсь, я добавлю в эту программу код, который защитит чтение от сбоев.Позвольте мне объяснить немного лучше.Скажем, к примеру, в коде реализовано много операций чтения.На данный момент есть только два чтения.В конце концов я буду запускать этот код с большим количеством операций чтения.Теперь скажите, что я запускаю тестовую программу и по какой-то причине я теряю соединение с ПЛК.Я хотел бы, чтобы программа делала одну из двух вещей: 1) Как только соединение потеряно, повторите попытку подключения определенное количество раз, а когда не хватит попыток, выйдите.или 2) Каким-то образом продолжайте чтение из ПЛК, пока все они не будут завершены.

Надеюсь, этого достаточно, чтобы получить помощь.Я опубликую код, который я так долго искал, без какой-либо идеи, как это сделать эффективно.Спасибо всем заранее.

#define PLAY_WITH_KEEPALIVE
#include <stdlib.h>
#include <stdio.h>
#include "nodavesimple.h"
#include "openSocket.h"


#ifdef PLAY_WITH_KEEPALIVE
#include <winsock.h>
#endif


int main(int argc, char **argv) {
    int a,b,c,res, doRun, doStop, doRead, doreadFlag, useProtocol, useSlot;
#ifdef PLAY_WITH_KEEPALIVE      
    int opt;
#endif    
    float d;
    daveInterface * di;
    daveConnection * dc;
    _daveOSserialType fds;
    doRun=0;
    doStop=0;
    doRead=0;
    doreadFlag=0;
    useProtocol=daveProtoISOTCP;
    useSlot=2;


 fds.rfd=openSocket(102, argv[1]);
    #ifdef PLAY_WITH_KEEPALIVE
    errno=0;    
    opt=1;
   //res=setsockopt(fds.rfd, SOL_SOCKET, SO_KEEPALIVE, &opt, 4);
   //LOG3("setsockopt %s %d\n", strerror(errno),res);
    #endif
 fds.wfd=fds.rfd;

    if (fds.rfd>0) 
        { 
        di =daveNewInterface(fds,"IF1",0, daveProtoISOTCP, daveSpeed187k);
        daveSetTimeout(di,5000000);
        dc =daveNewConnection(di,2,0, 2);  // insert your rack and slot here



            if (0==daveConnectPLC(dc)) 
                {
                    printf("Connected.\n");

                res=daveReadBytes(dc,daveFlags,0,0,16,NULL);
                if (0==res)  
                { 
                        a=daveGetU32(dc);
                        b=daveGetU32(dc);
                        c=daveGetU32(dc);
                        d=daveGetFloat(dc);
                    printf("FD0: %d\n",a);
                    printf("FD4: %d\n",b);
                    printf("FD8: %d\n",c);
                    printf("FD12: %f\n",d);
                }//end 0==res

                }//end daveConnectPLC


            else 

            {
        printf("Couldn't connect to PLC.\n Please make sure you use the -2 option with a CP243 but not with CPs 343 or 443.\n");    
        //closeSocket(fds.rfd);
        //return -2;
            }

    }//end fds.rfd



    fds.rfd=openSocket(102, argv[1]);
    fds.wfd=fds.rfd;

    if (fds.rfd>0) 
        { 
        di =daveNewInterface(fds,"IF1",0, daveProtoISOTCP, daveSpeed187k);
        daveSetTimeout(di,5000000);
        dc =daveNewConnection(di,2,0, 2);  // insert your rack and slot here


            if (0==daveConnectPLC(dc)) 
                {
                    printf("Connected.\n");

                res=daveReadBytes(dc,daveDB,1,0,64,NULL);
                if (0==res) 
                { 

                    a=daveGetU16(dc);
                    printf("DB1:DW0: %d\n",a);
                    a=daveGetU16(dc);
                    printf("DB1:DW1: %d\n...\n",a);
                    a=daveGetU16At(dc,62);
                    printf("DB1:DW32: %d\n",a);


                }//end 0==res

                    return 0;

                }//end daveConnectPLC
            else 

            {
        printf("Couldn't connect to PLC.\n Please make sure you use the -2 option with a CP243 but not with CPs 343 or 443.\n");    
        closeSocket(fds.rfd);
        return -2;
            }

    }//end fds.rfd






    else 
    {
    printf("Couldn't open TCP port. \nPlease make sure a CP is connected and the IP address is ok. \n");    
        return -1;
    }    



}// end main

Ответы [ 4 ]

1 голос
/ 07 июня 2012

Я тоже новый программист. Но хочу это сказать. Сначала мы должны различить соединение TCP/IP с картой ethernet ISO_TCP. Функция openSocket() устанавливает соединение с удаленным IP-адресом в заданном порту / услуге (102 ISO_TCP). Когда вызывается следующая функция daveNewInterface(), она инициализирует определенный интерфейс для подключения к ПЛК. После этого функция daveNewConnection() пытается открыть соединение по заданному адресу MPI, и, что очень важно, по заданной стойке и слоту. Если эта функция возвращает значение 0, она вызовет функцию daveConnectPLC() для подключения к ПЛК. На этом этапе установлено соединение Ethernet, а также соединение ПЛК. Теперь вы можете использовать все функции из библиотеки libnodave для чтения или записи данных, остановки или запуска ПЛК и многого другого.

В самом упрощенном коде TCP_ISO нет функции отключить адаптер или закрыть соединение с ПЛК, в вашем коде есть функция closeSocket(), а также функция, которая возвращает -2. Найдите, на какой строке происходит разрыв кода, например, вводя журнал после каждой функции, чтобы увидеть возвращаемые значения.

1 голос
/ 16 августа 2011

Вы должны проверить возвращаемое значение функции daveReadBytes.Если он не равен нулю, что-то пошло не так, и вы можете использовать функцию daveStrerror, чтобы получить правильное сообщение об ошибке:

printf ("error: %s\n", daveStrerror(res));

После этого вы можете решить либо просто повторить попыткучтение или отключение (с помощью closeSocket (...)), а затем создать новое подключение с самого начала.Проверьте документацию о том, какие есть коды ошибок.Некоторые ошибки не могут быть устранены повторной попыткой (например, потому что вы пытаетесь прочитать несуществующий блок данных).

1 голос
/ 28 сентября 2011

У меня есть цикл, который пытается подключиться 3 раза и корректно завершается в случае сбоя Возможно, вы сможете написать какой-то другой код, чтобы сначала проверить, установлено ли соединение, а также работает ли ПЛК. Обычно, если вы пытаетесь подключиться к IP-адресу, который не нужен; он там будет висеть и связывать ресурсы ...

0 голосов
/ 15 августа 2011

Вся информация для обнаружения потери связи находится в документации.

...