Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 15 von 31 ErsteErste ... 5131415161725 ... LetzteLetzte
Ergebnis 141 bis 150 von 304

Thema: DotNetSiemensPLCToolBoxLibrary (LibNoDave) Zugriff auf Dual-Port RAM / FB15

  1. #141
    Registriert seit
    29.03.2004
    Beiträge
    5.735
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Habs gefunden, die davePutProgramBlock() ist nur bei Jochens Bibliothek enthalten.

    @Hans54216:
    Es wäre nützlich, wenn du nochmal ein paar Aufzeichnungen eines Downloads von verschieden großen Dateien erstellen könntest.

    Meine Vermutung ist, dass nach der Anfrage "Request download" im 1. Byte der Antwort die Anzahl an Telegrammen steht, die ohne Abwarten einer Antwort an die NC geschickt werden dürfen (unackcount).
    Also steht dort z.B.eine 10, dann können 10 Telegramme gesendet werden, dann gibt es eine Antwort von der NC mit wieder einer neuen Anzahl, dann weitersenden usw. bis fertig.

    Bei deinem großen Upload des HMI aus deinem anderen Thread passt das auch gut zusammen.

    Bei deinem Anhang "NC_File_Big_Upload" gibt es aber eine Unstimmigkeit.
    - Erste Antwort auf download request: NC sagt unackcount=1
    - 1 Telegramm schicken, Antwort abwarten, NC sagt unackcount=18
    - Es werden aber nur 8 Telegramme geschickt, dann kann man am Zeitstempel sehen, dass etwas gewartet wird, und dann kommt tatsächlich eine Antwort von der NC mit unackcount = 8
    - Dann folgt aber nur noch 1 Telegramm und dann ist die Übertragung abgeschlossen

    Entweder meine Interpretation des Feldes (unackcount) ist falsch, oder es muss das Verhalten per Definition zwischen den Partnern vereinbart sein (1 Telegramm schicken, abwarten, 8 Telegramme schicken, abwarten), was ich mir aber nicht wirklich vorstellen kann.
    Die Genialität einer Konstruktion liegt in ihrer Einfachheit – Kompliziert bauen kann jeder.

    (Sergei Pawlowitsch Koroljow, sowjetischer Konstrukteur von Raketen und Weltraumpionier)

  2. #142
    Registriert seit
    17.06.2004
    Ort
    Offenau
    Beiträge
    3.745
    Danke
    209
    Erhielt 421 Danke für 338 Beiträge

    Standard

    davePutProgramBlock habe ich aus dem beispiel program erzeugt:

    https://github.com/dotnetprojects/Do...nodave.c#L6208
    ---------------------------------------------
    Jochen Kühner
    https://github.com/jogibear9988/DotN...ToolBoxLibrary - Bibliothek zur Kommunikation mit PLCs und zum öffnen von Step 5/7 Projekten

  3. #143
    Registriert seit
    29.03.2004
    Beiträge
    5.735
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard

    Zitat Zitat von Jochen Kühner Beitrag anzeigen
    davePutProgramBlock habe ich aus dem beispiel program erzeugt:

    https://github.com/dotnetprojects/Do...nodave.c#L6208
    Diese Zeilen finde ich fragwürdig:
    6251:
    Code:
    memcpy(progBlock+4,buffer,maxPBlockLen);
    und 6297:
    Code:
    memcpy(progBlock+4,buffer+(cnt*maxPBlockLen),maxPBlockLen);
    Wenn der Buffer nicht ein Vielfaches von maxPBlockLen, wird aus ganz anderem Speicher gelesen. Der wird zwar nicht verschickt, aber das ist trotzdem nicht statthaft.
    Und length als Zeiger übergeben, obwohl das überhaupt nicht notwendig ist.
    Die Genialität einer Konstruktion liegt in ihrer Einfachheit – Kompliziert bauen kann jeder.

    (Sergei Pawlowitsch Koroljow, sowjetischer Konstrukteur von Raketen und Weltraumpionier)

  4. #144
    Registriert seit
    29.03.2004
    Beiträge
    5.735
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard

    Ich habe mal die notwendigen Funktionen dafür erstellt, die zur Zeit so arbeiten wie ich es oben beschrieben habe. Wahrscheinlich wirds nicht funktionieren, wenn die NC sich so verhält wie in deinem einzigen Logfile vom Download einer großen Datei. Bei einer kleinen Datei deren Inhalt in eine PDU passt, sollte es hoffentlich funktionieren.

    Es wird noch eine Funktion benötigt, die eine PDU nur absendet und nicht auf Antwort wartet. Soweit ich weiß gibt es diese noch nicht. Für TCP könnte die so aussehen:
    Code:
    /* Sendet eine PDU, ohne auf Antwort zu warten */
    int DECL2 
    _daveSendTCP(daveConnection *dc, PDU *p)
    {
        int res, totLen, sLen;
    
        if (daveDebug & daveDebugExchange) {
            LOG2("%s enter _daveSendTCP\n", dc->iface->name);
        }
        dc->partPos = 0;
        totLen = p->hlen + p->plen + p->dlen;
        while (totLen) {
            if (totLen>dc->TPDUsize) {
                sLen = dc->TPDUsize;
                *(dc->msgOut + dc->partPos + 6) = 0x00;
            } else {
                sLen = totLen;
                *(dc->msgOut + dc->partPos + 6) = 0x80;
            }
            *(dc->msgOut + dc->partPos + 5) = 0xf0;
            *(dc->msgOut + dc->partPos + 4) = 0x02;
            _daveSendISOPacket(dc, 3 + sLen);
            totLen -= sLen;
            dc->partPos += sLen;
        }
        return 0;
    }
    Und die davePutNCProgram:
    Code:
    int DECL2 
    davePutNCProgram(daveConnection *dc, char *filename, char *buffer, int length)
    {
        PDU p, p2;
        int res = 0;
        int cnt = 0;
        int size = 0;
        uc unackcount;
        uc seq_num;
        uc dataunitref;
        int blockCont;
        int max_data_len;
        int filename_len;
    
        /* Request download */
        uc req_down_pa[]= {
            0x00, 0x01, 0x12, 0x04, 0x11, 0x7f, 0x01, 0x00
        };
        uc req_down_da[]= {
            0xff, 0x09, 0x00, 32,
            /* Dateiname max. 32 Zeichen */
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00
        };
    
        /* Download block */
        uc do_down_pa[]= {
            0x00, 0x01, 0x12, 0x08, 0x12, 0x3f, 0x02,
            0x00,       /* sequence number */
            0x00,       /* data unit reference */
            0x01,       /* Last data unit: 0=yes, 1=no */
            0x00, 0x00  /* errorcode */
        };
        /* 1920 ist die von libnodave vorgeschlagene max. PDU-Größe */
        uc do_down_da[1920 + 6]= {
            0xff, 0x09,
            0x00, 0x00, /* block size in bytes */
            0x00, 0xfb,
        };
    
        /* End download */
        uc end_down_pa[]= {
            0x00, 0x01, 0x12, 0x04, 0x11, 0x7f, 0x04,
            0x00       /* sequence number */
        };
        uc end_down_da[]= { 
            0xff, 0x09, 0x00, 0x02, 0x00, 0x00
        };
    
        filename_len = strlen(filename);    /* max. 32 chars */
        if (filename_len > 32) {
            return -1;
        }
        req_down_da[3] = filename_len;
        memcpy(&req_down_da[4], filename, filename_len);
    
        p.header = dc->msgOut + dc->PDUstartO;
        _daveInitPDUheader(&p, 7);
        _daveAddParam(&p, req_down_pa, sizeof(req_down_pa));
        _daveAddData(&p, req_down_da, 4 + filename_len);
    
        res = _daveExchange(dc, &p);
        if (res == daveResOK) {
            res = _daveSetupReceivedPDU(dc, &p2);
            if (daveGetDebug() & daveDebugPDU) {
                _daveDumpPDU(&p2);
            }
            /* Errorcode im Parameterteil prüfen */
            res = daveGetU16from(&p2.param[10]);
    
            if (res == 0) {
                seq_num = p2.param[9];      /* Diesen Wert für alle folgenden Downloadtelegramme verwenden */
                unackcount = p2.data[4];    /* Anzahl an Paketen die gesendet werden dürfen, ohne auf ein Ack zu warten */
    
                dataunitref = 0;
                do_down_pa[7] = seq_num;
                blockCont = 1;
                cnt = 0;
    
                /* Max. Länge in datablock = PDUsize - hlen - plen - dheader */
                max_data_len = daveGetMaxPDULen(dc) - 10 - 12 - 6;
    
                /* Daten senden bis unackcount = 0, dann auf Antwort warten, usw. usf. */
                do {
                    do_down_pa[8] = ++dataunitref;
    
                    p.header = dc->msgOut + dc->PDUstartO;
                    _daveInitPDUheader(&p, 7);
                    size = max_data_len;
    
                    if (length > ((cnt+1) * max_data_len)) {
                        do_down_pa[9] = 1;  /* Last data unit: 1=no */
                    } else {
                        size = length - (cnt * max_data_len);
                        do_down_pa[9] = 0;	/* Last data unit: 0=yes */
                        blockCont = 0;
                    }
                    do_down_da[2] = size / 256;
                    do_down_da[3] = size % 256;
    
                    memcpy(do_down_da + 6, buffer + (cnt * max_data_len), size);
    
                    _daveAddParam(&p, do_down_pa, sizeof(do_down_pa));
                    _daveAddData(&p, do_down_da, size + 6);
                    if (daveGetDebug() & daveDebugPDU) {
                        _daveDumpPDU(&p);
                    }
                    if ((--unackcount > 0) || (blockCont == 0)) {
                        /* PDU senden ohne auf Antwort zu warten */
                        res = _daveSendTCP(dc, &p);
                        if (res != daveResOK) {
                            break;
                        }
                    } else {
                        /* PDU senden mit Warten auf Antwort von NC */
                        LOG2("davePutNCProgram: unackcount=%d, warte auf Antwort von NC um fortzusetzen...\n", unackcount);
                        res = _daveExchange(dc, &p);
                        if (res == daveResOK) {
                            res = _daveSetupReceivedPDU(dc, &p2);
                            if (daveGetDebug() & daveDebugPDU) {
                                _daveDumpPDU(&p2);
                            }
                            /* Hier weiß ich nicht wie ein Fehler auszuwerten ist, da weder im
                             * Kopf- noch im Parameterteil ein Errorcode vorhanden ist.
                             * Bei Erfolg sollte der Datenteil 6 Bytes groß sein, und unackcount > 0
                             */
    
                            /*              push-nc                   continue */
                            if ((p2.param[5] == 0x3f && p2.param[6] == 0x03) &&
                               ((PDUHeader*)p2.header)->dlen == 6) {
                                unackcount = p2.data[4];    /* Anzahl an Paketen die gesendet werden dürfen, ohne auf ein Ack zu warten */
                                if (unackcount == 0) {
                                    LOG2("davePutNCProgram: in continue response unackcount=%d. Exit!\n", unackcount);
                                    res = daveResUnexpectedFunc;
                                    break;
                                }
                            } else {
                                LOG2("davePutNCProgram: in continue response, falscher Aufbau der Antwort (p2.param[5] = %d). Exit!\n", p2.param[5]);
                                res = daveResUnexpectedFunc;
                                break;
                            }
                        } else {
                            break;
                        }
                    }
                    cnt++;
                } while (blockCont);
    
                if (res == daveResOK) {
                    /* End-download senden */
                    end_down_pa[7] = seq_num;
                    p.header = dc->msgOut + dc->PDUstartO;
                    _daveInitPDUheader(&p, 7);
                    _daveAddParam(&p, end_down_pa, sizeof(end_down_pa));
                    _daveAddData(&p, end_down_da, sizeof(end_down_da));
                    res = _daveExchange(dc, &p);
                    /* Antwort auswerten */
                    if (res == daveResOK) {
                        res = _daveSetupReceivedPDU(dc, &p2);
                        if (daveGetDebug() & daveDebugPDU) {
                            _daveDumpPDU(&p2);
                        }
                        if (p2.param[5] == 0xbf && p2.param[6] == 0x05) {
                            /* Errorcode im Parameterteil prüfen */
                            res = daveGetU16from(&p2.param[10]);
                        } else {
                            res = daveResUnexpectedFunc;
                        }
                    }
                }
            } else {
                LOG2("davePutNCProgram: errorcode erster Antwort: %04X\n", res);
            }
        }
        return res;
    }
    Für den Dateinamen habe ich eine maximale Länge von 32 Zeichen erlaubt. Diese Länge ist auch in der Dokumentation der PI-Services angegeben.
    Die Genialität einer Konstruktion liegt in ihrer Einfachheit – Kompliziert bauen kann jeder.

    (Sergei Pawlowitsch Koroljow, sowjetischer Konstrukteur von Raketen und Weltraumpionier)

  5. #145
    Hans54216 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    06.04.2013
    Beiträge
    208
    Danke
    10
    Erhielt 5 Danke für 5 Beiträge

    Standard

    Anbei noch mal nen großen Upload + Download. Diesmal direkt mit dem Siemens HMI.
    WireShark_UpDownload2.rar

  6. #146
    Hans54216 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    06.04.2013
    Beiträge
    208
    Danke
    10
    Erhielt 5 Danke für 5 Beiträge

    Standard

    Wollte die Funktionen gerade testen. Beim compilieren kam, das "dc->partPos" und "dc->TPDUsize" fehlen.

    Hab diese dann aus "libnodave-0.8.5" übernommen. (in die Struktur + in den Funktionen ("_daveExchangeTCP", "_daveSendISOPacket"))

    Hat aber wohl nicht funktioniert. Kann nun keine Verbindung zur Steuerung aufbauen. Laut Wireshark wird auch kein Paket verschickt.

  7. #147
    Registriert seit
    29.03.2004
    Beiträge
    5.735
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard

    Ja, das ist der Teil bei dem große S7-PDUs bei Bedarf in kleinere TPDUs gesplittet werden. Das ist bei Jochens Version nicht enthalten. Musst mal gucken wie bei ihm die daveExchangeTCP Funktion aussieht, da kannst du mehr oder weniger den ersten Code zum Senden übernehmen, und löschst nur den zweiten Teil bei dem Empfangen wird raus.

    Ich teste das nur mit libnodave 0.8.5.1, da lässt sich das übersetzen, und es gehen auch Daten raus.

    Aber ich kann für den Download absolut keine Logik erkennen, wann die NC nach welcher Anzahl eine Bestätigungsnachricht sendet. In deinem letzten Mitschnitt kommen diese Telegramme ja völlig unregelmäßig rein.
    Insgesamt sind es 66 Telegramme zum Download. Wenn das erste Byte im Datenteil von der NC angibt wie viele Telegramme bestätigt werden, komme ich dort in Summe auf 1 + 18 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 = 83.
    Und wenn ich annehme, die beiden Bytes geben eine Summe an Bytes an die bestätigt werden, dann komme ich auch auf keinen sinnvollen Wert.

    Man muss schon wissen wann eine Antwort zu erwarten ist, andernfalls funktioniert das so nicht. Oder man muss nach jedem Senden kurz warten und gucken ob was im Empfangspuffer ist, und wenn nicht dann einfach weitersenden. Das ist aber garantiert nicht so geplant. Kann auch sein dass ich da völlig auf dem Holzweg bin.

    Man könnte höchstens an einer NC mal testen, in dem man einzelne Telegramme um z.B. 2s verzögert nacheinander rausschickt, und guckt wann denn da was zurückkommt.
    Die Genialität einer Konstruktion liegt in ihrer Einfachheit – Kompliziert bauen kann jeder.

    (Sergei Pawlowitsch Koroljow, sowjetischer Konstrukteur von Raketen und Weltraumpionier)

  8. #148
    Registriert seit
    29.03.2004
    Beiträge
    5.735
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard

    Beim Download scheint es auch nochmal ein Kopfteil zu geben, zumindest wenn du dort die Datei im Archiv hochgeladen hast. Also da muss man wohl auch noch etwas voranstellen.

    Code:
    00058934160509080243    ;$PATH=/_N_WKS_DIR/_N_TEST_JE_WPD
    Dateigröße ist 58900 Bytes.
    Alle Bytes die beim Download übertragen werden sind in Summe 58958 Bytes (Netto, d.h. ohne 2 Bytes Kopf pro Datenpaket /PDU).

    Wenn man den ersten Teil auftrennt in
    00058934
    16050908
    0243

    Der hinzugefügte Kopfstring ist inkl. abschließendem Newline 58 Zeichen lang. Wie ich auch rechne komme ich nicht auf 58934. Und die anderen Zahlenwerte sagen mir auch nichts, genausowenig wie der Pfad der dort eingebaut wird.
    Geändert von Thomas_v2.1 (09.05.2016 um 19:30 Uhr)
    Die Genialität einer Konstruktion liegt in ihrer Einfachheit – Kompliziert bauen kann jeder.

    (Sergei Pawlowitsch Koroljow, sowjetischer Konstrukteur von Raketen und Weltraumpionier)

  9. #149
    Hans54216 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    06.04.2013
    Beiträge
    208
    Danke
    10
    Erhielt 5 Danke für 5 Beiträge

    Standard

    Zitat Zitat von Thomas_v2.1 Beitrag anzeigen
    Code:
    00058934160509080243    ;$PATH=/_N_WKS_DIR/_N_TEST_JE_WPD
    Und die anderen Zahlenwerte sagen mir auch nichts, genausowenig wie der Pfad der dort eingebaut wird.
    Der Pfad bedeutet:
    WKS.dir -> Standartverzeichnis Werkstücke
    TEST_JE.wpd -> Ordnername

    Was die Nummer bedeutet weiß ich nicht.

  10. #150
    Registriert seit
    29.03.2004
    Beiträge
    5.735
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Habs raus.
    Die ersten 8 Zeichen sind Länge Dateiinhalt + Länge Pfadangabe. Alles ab ";" zählt sozusagen zu dieser Länge.
    Der Rest ist der Zeitstempel der Datei:

    160509080243=
    09.05.2016, 08:02:43 Uhr

    Den Zeitstempel zeigt zumindest auch der Windows Explorer.

    Das kann ich in die Funktion noch mit einbauen. Woher soll der Zeitstempel kommen, als Parameter, oder aktuelle Zeit verwenden?

    Problem ist also weiterhin nur die Anzahl an Telegrammen nach denen auf eine Antwort von der NC zu warten ist.
    Die Genialität einer Konstruktion liegt in ihrer Einfachheit – Kompliziert bauen kann jeder.

    (Sergei Pawlowitsch Koroljow, sowjetischer Konstrukteur von Raketen und Weltraumpionier)

Ähnliche Themen

  1. Zugriff auf WinAC RTX mit LibnoDave
    Von rm2001 im Forum Hochsprachen - OPC
    Antworten: 2
    Letzter Beitrag: 27.04.2012, 20:31
  2. Libnodave & VB.NET Zugriff auf geschützte Speicherbereiche
    Von KJ1234 im Forum Hochsprachen - OPC
    Antworten: 1
    Letzter Beitrag: 10.11.2007, 16:02
  3. Zugriff mit libnodave (unter Delphi) auf S7-CP443-1
    Von Frank im Forum Hochsprachen - OPC
    Antworten: 19
    Letzter Beitrag: 29.04.2007, 13:59
  4. Zugriff auf Siemens S7 per libnodave (MPI)
    Von Anonymous im Forum Hochsprachen - OPC
    Antworten: 15
    Letzter Beitrag: 02.11.2005, 17:09
  5. Fehler bei Zugriff auf COM- Port
    Von h_matthias im Forum Simatic
    Antworten: 16
    Letzter Beitrag: 08.03.2004, 22:14

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •