EtherCAT之对象字典解析

时间:2022-03-10 17:15:44

原文地址:http://blog.csdn.net/huangxianxinalice/article/details/10956137

关于对象字典的数据结构如下:

[cpp] view plain copy
  1. /*///////////////////////////////////////////////////////////////////////////////////////// 
  2. // 
  3. //    Object dictionary entry structure 
  4. */  
  5.   
  6. typedef struct OBJ_ENTRY  
  7. {  
  8. #if !STATIC_OBJECT_DIC  
  9.     struct OBJ_ENTRY                      *pPrev;                    //previous entry(object) in the object dictionary list  
  10.     struct OBJ_ENTRY                      *pNext;                    //next entry(object) in the object dictionary list  
  11. #endif //#if !STATIC_OBJECT_DIC  
  12.   
  13.     UINT16                                Index;  
  14.     TSDOINFOOBJDESC                       ObjDesc;  
  15.     OBJCONST TSDOINFOENTRYDESC OBJMEM     *pEntryDesc;  
  16.     OBJCONST UCHAR OBJMEM                 *pName;  
  17.     void MBXMEM                           *pVarPtr;  
  18.     UINT8 (* Read)( UINT16 Index, UINT8 Subindex, UINT32 Size, UINT16 MBXMEM * pData, UINT8 bCompleteAccess );  
  19.     UINT8 (* Write)( UINT16 Index, UINT8 Subindex, UINT32 Size, UINT16 MBXMEM * pData, UINT8 bCompleteAccess );  
  20.     UINT16                                 NonVolatileOffset;  
  21. }  
  22. TOBJECT;  
EtherCAT之对象字典解析

代码1

对象字典的对象的数据结构是采用链表的形式,组成整个对象字典。

其中,在对象里面定义了索引,对象的描述,SDO入口指针的描述,对象字典的名称,变量的指针,还定义了读和写两个虚函数

ObjDesc的数据结构如下:

[cpp] view plain copy
  1. typedef struct MBX_STRUCT_PACKED_START  
  2. {  
  3.     UINT16            DataType;            // 关于索引的数据类型  
  4.     UINT16            ObjFlags;  
  5.     /*对象代码和最大子索引将被人为得设置在对象字典里面,这个值经常以大端模式被创造 */  
  6.     #define    OBJFLAGS_MAXSUBINDEXMASK    0x00FF//最大子索引的掩码  
  7.     #define    OBJFLAGS_MAXSUBINDEXSHIFT   0<span style="white-space:pre">  </span> //最大子索引的偏移  
  8.     #define    OBJFLAGS_OBJCODEMASK        0x0F00//对象的掩码  
  9.     #define    OBJFLAGS_OBJCODESHIFT       8<span style="white-space:pre">  </span> //对象的偏移  
  10.   
  11.     #define    OBJCODE_VAR                 0x07  
  12.     #define    OBJCODE_ARR                 0x08  
  13.     #define    OBJCODE_REC                 0x09  
  14. //        char                Name[];                // rest of mailbox data  
  15. }MBX_STRUCT_PACKED_END  
  16. TSDOINFOOBJDESC;  
代码2
其中,对于OBJCODE里面这三个宏定义OBJCODE_VAR  OBJCODE_ARR  OBJCODE_REC (请问这三个宏定义分别代表着哪三种情况)

从字面上的意思来说,OBJCODE的变量,OBJCODE的队列,OBJCODE的记录

OBJCODE通过函数  

 UINT8 objCode = (pObjEntry->ObjDesc.ObjFlags & OBJFLAGS_OBJCODEMASK) >> OBJFLAGS_OBJCODESHIFT;

最后,得出的是OBJCODE的类别

如果是变量的话,就return 0;

如果是对象的队列和记录得话,则可以得出OBJCODE的偏移量

如果对象字典object code的类别得出是OBJCODE的队列的时候,得出对象字典的入口地址是&pObjEntry->pEntryDesc[1];

如果,是OBJCODE_REC的时候,得出的对象字典的入口地址是&pObjEntryDesc[i];

Obj_Desc的作用是为了找到关于对象的描述


SDO入口地址的描述

[cpp] view plain copy
  1. // SDO Information / Entry Description:  
  2. typedef struct MBX_STRUCT_PACKED_START  
  3. {  
  4.     UINT16                DataType;                // 关于索引的数据类型  
  5.     UINT16                BitLength;  
  6.     UINT16                ObjAccess;                // Bit 0: Read Access in Pre-Op  
  7.                                                     // Bit 1: Read Access in Safe-Op  
  8.                                                     // Bit 2: Read Access in Op  
  9.                                               <span style="white-space:pre">    </span>    // Bit 3: Write Access in Pre-Op  
  10.                                             <span style="white-space:pre">  </span>    // Bit 4: Write Access in Safe-Op  
  11.                                           <span style="white-space:pre">    </span>    // Bit 5: Write Access in Op  
  12.                                           <span style="white-space:pre">    </span>    // Bit 6: mappable in RxPDO  
  13.                                           <span style="white-space:pre">    </span>    // Bit 7: mappable in TxPDO  
  14.                                          <span style="white-space:pre"> </span>    // Bit 8: entry will be included in backup  
  15.                                          <span style="white-space:pre"> </span>    // Bit 9: entry will be included in settings  
  16.   
  17.         #define    ACCESS_READWRITE             0x003F  
  18.         #define    ACCESS_READ                  0x0007  
  19.         #define    ACCESS_READ_PREOP            0x0001  
  20.         #define    ACCESS_READ_SAFEOP           0x0002  
  21.         #define    ACCESS_READ_OP               0x0004  
  22.         #define    ACCESS_WRITE                 0x0038  
  23.         #define    ACCESS_WRITE_PREOP           0x0008  
  24.         #define    ACCESS_WRITE_SAFEOP          0x0010  
  25.         #define    ACCESS_WRITE_OP              0x0020  
  26.         #define    OBJACCESS_NOPDOMAPPING       0x0000  
  27.         #define    OBJACCESS_RXPDOMAPPING       0x0040  
  28.         #define    OBJACCESS_TXPDOMAPPING       0x0080  
  29.         #define    OBJACCESS_BACKUP             0x0100  
  30.         #define    OBJACCESS_SETTINGS           0x0200  
  31.         #define    OBJACCESS_SAFEINPUTS         0x0400  
  32.         #define    OBJACCESS_SAFEOUTPUTS        0x0800  
  33.         #define    OBJACCESS_SAFEPARAMETER      0x1000  
  34. //        UINT16            UnitType;                // optional if bit3 of valueInfo  
  35. //        UINT8                DefaultValue[];        // optional if bit4 of valueInfo  
  36. //        UINT8                MinValue[];            // optional if bit5 of valueInfo  
  37. //        UINT8                MaxValue[];            // optional if bit6 of valueInfo  
  38. //        char                Desc[];                 // rest of mailbox data  
  39. }MBX_STRUCT_PACKED_END  
  40. TSDOINFOENTRYDESC;  
代码3

算法:
    for (i = 1; i <= subindex; i++)
    {
        /* get the entry description获得入口描述 */
        if (objCode == OBJCODE_ARR)
            pEntry = &pObjEntry->pEntryDesc[1];
        else
            pEntry = &pObjEntry->pEntryDesc[i];

这里根据子索引数找到相关的入口地址

其中,pObjEntry->pEntryDesc (见代码1),是定义了一个指针,指针类型是TSDOINFOENTRYDESC的结构体。那里上面的代码是指向它相邻的一个结构体的pEntryDesc吗?那这个pEntryDesc,是存放它第一个子索引的入口描述?

那它子索引的初始化是怎样初始化?