Beckhoff / ADS

Beckhoff protocol to communicate with TwinCAT devices.
MIT License
513 stars 194 forks source link

Solution on error code 1794 & 1797 on Linux(ubuntu x64) platform #80

Closed soulzhao closed 5 years ago

soulzhao commented 5 years ago

When we want to load symbols Info from AdsServer on a linux platform, we will use AdsSyncReadWriteReqEx2 to do that, a typical code snippet would be like below:

                AdsSymbolEntry  adsSymbolEntry;
        uint32_t bytesRead;

        long nErr = AdsSyncReadWriteReqEx2(
            newPort,
            &newRemote,
            ADSIGRP_SYM_INFOBYNAMEEX, //ADSIGRP_SYM_HNDBYNAME
            0x0,
            sizeof(adsSymbolEntry),
            &adsSymbolEntry,
            varName.size(),
            varName.c_str(),
            &bytesRead);

        if (nErr != 0) {
            ucout << "ADS get symbal info command error, error code::" << nErr << endl;
            return nErr;
        }

        TDataPair *pParReq = new TDataPair;
        pParReq->indexGroup = adsSymbolEntry.iGroup;
        pParReq->indexOffset = adsSymbolEntry.iOffs;
        pParReq->length = adsSymbolEntry.size;

With the TDataPair returned, we can use a TDataPair *symbalInfoPairs = new TDataPair[unKnownNames.size()]; to request a batch of variables' values in one time:

nErr = AdsSyncReadWriteReqEx2(
                    this->port,
                    &this->remote,
                    ADSIGRP_SUMUP_READ,     // ADS read command
                    reqNum,                 // number of ADS-Sub commands
                    4 * reqNum + reqSize,   // we expect an ADS-error-return-code (long) for each ADS-Sub command
                    (void*)(buffer),        // provide space for the response containing the return codes
                    12 * reqNum,            // cbyteLen : send 12 bytes (2 * long, IG, IO, Len) 
                    symbalInfoPairs,        // buffer with data
                    &bytesReaded
                );

The key data structs here are AdsSymbolEntry and TDataPair, we should pay more attention to these two structs as on linux and windows, they should have different definitions due to the different platform related data-type defines:

typedef struct dataPair
{
#ifdef _WIN32
    unsigned long indexGroup;   // index group in ADS server interface
    unsigned long indexOffset;  // index offset in ADS server interface
    unsigned long length;       // count of bytes to read
#else
    unsigned int  indexGroup;
    unsigned int  indexOffset;
    unsigned int  length;
#endif
} TDataPair;
typedef struct
{
#ifdef _WIN32
    unsigned    long        entryLength;    // length of complete symbol entry
    unsigned    long       iGroup;          // indexGroup of symbol: input, output etc.
    unsigned    long       iOffs;           // indexOffset of symbol
    unsigned    long       size;            // size of symbol ( in bytes, 0 = bit )
    unsigned    long        dataType;       // adsDataType of symbol
    unsigned    long        flags;          // see above
#else
    unsigned    int     entryLength;    // length of complete symbol entry
    unsigned    int     iGroup;         // indexGroup of symbol: input, output etc.
    unsigned    int     iOffs;          // indexOffset of symbol
    unsigned    int     size;           // size of symbol ( in bytes, 0 = bit )
    unsigned    int     dataType;       // adsDataType of symbol
    unsigned    int     flags;          // see above
#endif

    unsigned    short       nameLength;     // length of symbol name (excl. \0)
    unsigned    short       typeLength;     // length of type name (excl. \0)
    unsigned    short       commentLength;  // length of comment (excl. \0)
} AdsSymbolEntry, *PAdsSymbolEntry, **PPAdsSymbolEntry;

This is the reason I found to most 1794 & 1797 issues reported on Linux platform

pbruenn commented 5 years ago

Thanks for investing the time to explain your use case. Indeed I think it might be a pretty common issue. So I tried to fix it by adding struct AdsSymbolEntry and struct AdsSymbolInfoByName to AdsLib.h. AdsSymbolInfoByName should be the same as TDataPair, but I found the name better. I think now it's time to add a ADS SUM example #53 , too ;-). But today I hadn't time to implement more.