SDO处理过程(一)

  1.         /* the last SDO is still in work */  
  2.         return MBXERR_SERVICEINWORK;  
  3.     }  
  4. #endif  
  5. /*根据SDO的不同的服务类型,选择想对应的SDO服务*/  
  6.     switch (command)  
  7.     {  
  8.     case SDOSERVICE_INITIATEDOWNLOADREQ:  
  9.     case SDOSERVICE_INITIATEUPLOADREQ:  
  10.         /* the variable index contains the requested index of the SDO service */  
[cpp]  view plain  copy
  1. /*这个变量索引包含需要的SDO服务的索引*/  
  2. index = pSdoInd->SdoHeader.Sdo[SDOHEADER_INDEXHIOFFSET] & SDOHEADER_INDEXHIMASK;  
  3. index <<= 8;  
  4. index += pSdoInd->SdoHeader.Sdo[SDOHEADER_INDEXLOOFFSET] >> SDOHEADER_INDEXLOSHIFT;  
  5. /* the variable subindex contains the requested subindex of the SDO service */  
[cpp]  view plain  copy
  1. <span style="white-space:pre">  </span>/*子索引的变量包含需要的SDO服务需要的子索引*/  
  2.         subindex    = pSdoInd->SdoHeader.Sdo[SDOHEADER_SUBINDEXOFFSET] >> SDOHEADER_SUBINDEXSHIFT;  
  3.   
  4.         /* OBJ_GetObjectHandle checks if the requested index is defined in the object dictionary */  
[cpp]  view plain  copy
  1. <span style="white-space:pre">  </span>/*OBJ_GetObjectHandle检查是否需要的index是否在对象字典里面定义,并获得它的句柄*/  
  2.         pObjEntry = OBJ_GetObjectHandle( index );  
  3.   
  4.         if ( pObjEntry )  
  5.         {  
[cpp]  view plain  copy
  1. <span style="white-space:pre">  </span>    /*如果在搜寻所有的对象字典之后,得到所需要索引的句柄*/  
  2.             /* transferType contains the information if the SDO Download Request or the SDO Upload Response 
  3.                can be an expedited service (SDO data length <= 4, that means the data is stored in the 
  4.                 SDO-Header completely */  
[cpp]  view plain  copy
  1. <span style="white-space:pre">  </span>    /*transferType包含那些信息,是否SDO 下载请求和SDO 上传响应可以是快速服务类型(SDO数据长度小于等于4个字节,数据可以完全放在SDO-Header里面)*/  
  2.             UINT8 bTransferType = 0;  
  3.             /* pData is the pointer to the received (SDO-Download) or sent (SDO-Upload) SDO data in the mailbox */  
[cpp]  view plain  copy
  1. <span style="white-space:pre">  </span>    /*pData是一个指针指向在邮箱里面,SDO下载和SDO上传的对象字典的数据*/  
  2.             UINT16 MBXMEM * pData = NULL;  
  3. #if SEGMENTED_SDO_SUPPORTED  
  4.             UINT8 segTransfer = 0;  
  5. #endif  
  6.   
  7.             {  
  8.                 dataSize = objLength = OBJ_GetObjectLength( index, subindex, pObjEntry, (UINT8) (sdoHeader & SDOHEADER_COMPLETEACCESS) );  
  9.   
  10.                 if ( command == SDOSERVICE_INITIATEUPLOADREQ )//如果SDO里面的命令是SDO上传请求的话  
  11.                 {  
[cpp]  view plain  copy
  1. <span style="white-space:pre">      </span>/*如果SDO里面的对象字典的长度小于等于MAX_EXPEDITED_DATA和不等于零的时候,则是快速类型的上传模式*/  
  2.                     /* SDO Upload */  
  3.                     if ( mbxSize != EXPEDITED_FRAME_SIZE )  
  4.                         /* a SDO Upload request has always a fixed size (2 Byte CoE-Header plus 8 Byte SDO-Header) */  
  5.                         return MBXERR_INVALIDSIZE;  
  6.                     /* distinguish between expedited and normal upload response within the length of the response data */  
  7.                     if ( (objLength <= MAX_EXPEDITED_DATA) && objLength != 0 )  
  8.                     {  
  9.                         /* Expedited Upload */  
  10.                         bTransferType = 1;  
  11.                         /* pData is the pointer where the object data has to be copied for the response */  
[cpp]  view plain  copy
  1. <span style="white-space:pre">          </span>/*pData是一个指针,它指向的对象字典数据被复制对应的数据作为响应*/  
[cpp]  view plain  copy
  1. pData = ((TINITSDOUPLOADEXPRESMBX MBXMEM *) pSdoInd)->Data;  
  2. /* initialize the 4 data bytes of the SDO upload response because the requested object data 
  3.    could be less than 4 */  
[cpp]  view plain  copy
  1. <span style="white-space:pre">          </span>/*因为请求的对象数据是小于4个字节,初始化4个字节数据给SDO上传响应*/  
  2.                         pData[0] = 0;  
  3.                         pData[1] = 0;  
  4.                     }  
  5.                     else<span style="white-space:pre">  </span>//这个else是对应上面的((objLength<=MAX_EXPEDITED_DATA)&& objLength !=0) 如果对象字典的长度大于MAX_EXPEDITED_DATA也就是4个字节的时候。则说明上传是分段上传模式或者是正常上传模式。  
  6.                     {  
  7.   
  8.                     dataSize = u16SendMbxSize - MBX_HEADER_SIZE - UPLOAD_NORM_RES_SIZE;  
  9. <span style="white-space:pre">          </span>/*如果对象字典的长度比邮箱对象数据区的长度还要打的时候,说明是要采用分段类型的形式上传数据*/  
  10.                         if ( dataSize < objLength )  
  11.                             /* Segmented Upload */  
  12.                             segTransfer = 1;  
[cpp]  view plain  copy
  1. else  
  2. :pre">          </span>/*否则采用正常上传模式*/  
[cpp]  view plain  copy
  1. /* Normal Upload */  
  2. pData = ((TINITSDOUPLOADNORMRESMBX MBXMEM *) pSdoInd)->Data;  
[cpp]  view plain  copy
  1. <span style="white-space:pre">          </span>    /*pData指向对象字典的数据区地址*/  
  2. #else/*如果从站本身不支持分段上传模式的话,则不需要上面的判断*/  
  3.                         /* Normal Upload */  
  4.                         /* pData is the pointer where the object data has to be copied for the response */  
[cpp]  view plain  copy
  1. <span style="white-space:pre">          </span>/*pData是一个指针,作为响应,指向的地方对象字典的数据应该被拷贝*/  
  2.                         pData = ((TINITSDOUPLOADNORMRESMBX MBXMEM *) pSdoInd)->Data;  
  3. #endif  
  4.                     }  
  5.                 }  
  6.                 else//如果对象字典的命令,不是SDO上传命令的话  
  7.                 {  
  8.                     /* SDO-Download: store if the request is a expedited or normal request 判断是否为快速还是普通请求 */  
  9.                     bTransferType = sdoHeader & SDOHEADER_TRANSFERTYPE;  
  10.                 }  
  11.             }  
  12.   
  13.             if ( command == SDOSERVICE_INITIATEDOWNLOADREQ )//如果SDO的命令是下载请求  
  14.             {  
  15.                 /* SDO Download */  
  16.                 if ( bTransferType )//根据前面判断是否为快速下载请求  
  17.                 {  
  18.                     /* Expedited Download */  
  19.                     if ( mbxSize != EXPEDITED_FRAME_SIZE )  
  20.                         /* an Expedited SDO Download request has always a fixed size (2 Byte CoE-Header plus 8 Byte SDO-Header) */  
  21.                         return MBXERR_INVALIDSIZE;  
  22.                     /* dataSize gets the real size of the downloaded object data (1,2,3 or 4) */  
  23.                     dataSize = MAX_EXPEDITED_DATA - ((sdoHeader & SDOHEADER_DATASETSIZE) >> SDOHEADERSHIFT_DATASETSIZE);  
  24.                     /* pData is the pointer to the downloaded object data */  
[cpp]  view plain  copy
  1. <span style="white-space:pre">      </span>   //pData是一个指针指向SDO的数据区  
  2.                     pData = (UINT16 MBXMEM *) &pSdoInd[1];  
  3.                 }  
  4.                 else//如果不是快速下载请求  
  5.                 {  
  6.                     /* Normal Download */  
  7.                     /* downloadSize gets the real size of the downloaded data */  
  8.                     /* '&' operator was too much */  
  9.   
  10.                     UINT32 downloadSize = ((UINT32)(SWAPWORD(((TINITSDODOWNLOADNORMREQMBX MBXMEM *) pSdoInd)->CompleteSize[1]))<<16) + (SWAPWORD(((TINITSDODOWNLOADNORMREQMBX MBXMEM *) pSdoInd)->CompleteSize[0]));  
  11.   
  12.                     /* HBu 29.03.06: if it is a segmented download the mbxSize has to be the complete mailbox size */  
  13.                     if ( (MBX_HEADER_SIZE+EXPEDITED_FRAME_SIZE+downloadSize) > u16ReceiveMbxSize )//如果它是一个分段下载类型,mbxSize毕业是一个完整的邮箱长度  
  14.                     {  
  15.                         if ( mbxSize != (u16ReceiveMbxSize-MBX_HEADER_SIZE) )  
  16.                             return MBXERR_INVALIDSIZE;  
  17.                     }  
  18.                     else  
  19.                     {  
  20.                         if ( mbxSize != (EXPEDITED_FRAME_SIZE+downloadSize) )  
  21.                             /* the mbxSize and the downloadSize are not consistent (mbxSize = downloadSize + 2 byte CoE-Header + 8 byte SDO Header */  
  22.                             return MBXERR_INVALIDSIZE;  
  23.                     }  
  24.   
  25.                     /* pData is the pointer to the downloaded object data */  
  26.                     pData = (UINT16 MBXMEM *) ((TINITSDODOWNLOADNORMREQMBX MBXMEM *) pSdoInd)->Data;//pData是一个指针指向下载对象的数据区  
  27.                     /* the received dataSize will be checked in the object specific functions called from 
  28.                        OBJ_Write (in objdef.c) */  
  29.                     dataSize = downloadSize;接受的dataSize多大将会被检查在对象特殊的函数,在OBJ_Write(在object.c文件里调用)  
[cpp]  view plain  copy
  1.                     if ( dataSize > (UINT32)(mbxSize - DOWNLOAD_NORM_REQ_SIZE) )//对象字典的长度大于mbxSize-DOWNLOAD_NORM_REQ_SIZE的时候  
  2. #if SEGMENTED_SDO_SUPPORTED  
  3.                         /* Segmented Download */  
  4.                         segTransfer = 1;//采用分段下载的形式  
  5. #else /* SEGMENTED_SDO_SUPPORTED */  
  6.                         abort = ABORTIDX_PARAM_LENGTH_ERROR;  
  7. #endif /* SEGMENTED_SDO_SUPPORTED */  
  8.                 }  
  9.             }  
  10.   
  11.             if ( sdoHeader & SDOHEADER_COMPLETEACCESS )//接下来对sdoHeader的是否完全操作进行判断  
  12. #if COMPLETE_ACCESS_SUPPORTED  
  13.             {  
  14.                 bCompleteAccess = 1;//可以完全操作  
  15.                 // HBu 02.05.06: Complete Access is only supported with subindex 0 and 1  
  16.                 if (subindex > 1)  
  17.                     abort = ABORTIDX_UNSUPPORTED_ACCESS;  
  18.             }  
  19. #else  
  20.                 abort = ABORTIDX_UNSUPPORTED_ACCESS;  
  21. #endif  
  22.   
  23.             if ( abort == 0 )//abort ==0,说明是可以完全操作子索引是0或者1  
  24.             {  
  25. #if SEGMENTED_SDO_SUPPORTED  
  26.                 if ( segTransfer )//如果可以分段传输  
  27.                 {  
  28.                     bSdoSegFollows         = TRUE;  
  29.                     bSdoSegLastToggle     = 1;  
  30. #if COMPLETE_ACCESS_SUPPORTED  
  31.                     bSdoSegAccess             = bCompleteAccess;  
  32. #endif  
  33.                     nSdoSegIndex             = index;  
  34.                     nSdoSegSubindex         = subindex;  
  35.                     pSdoSegObjEntry        = pObjEntry;  
  36.                     if ( command == SDOSERVICE_INITIATEUPLOADREQ )  
  37.                         nSdoSegCompleteSize    = objLength;  
  38.                     else  
  39.                         nSdoSegCompleteSize    = dataSize;  
  40.   
  41.                     if (pSdoSegData != NULL)  
  42.                     {  
  43.                         FREEMEM( (UINT16 VARMEM *) pSdoSegData);  
  44.                         pSdoSegData = NULL;  
  45.                     }  
  46. /*ECATCHANGE_START(V5.01) MBX1*/  
  47.                     pSdoSegData = (UINT16 VARMEM *) ALLOCMEM( ROUNDUPBYTE2WORD(nSdoSegCompleteSize) );  
  48. /*ECATCHANGE_END(V5.01) MBX1*/  
  49.   
  50.                     if ( pSdoSegData == NULL )  
  51.                         abort = ABORTIDX_OUT_OF_MEMORY;  
  52.                     else  
  53.                     {  
  54.                         if ( command == SDOSERVICE_INITIATEUPLOADREQ )  
  55.                         {  
  56.                             /* Segmented Upload */  
  57.                             abort = OBJ_Read( index, subindex, objLength, pObjEntry, (UINT16 MBXMEM *) pSdoSegData, bCompleteAccess );  
[cpp]  view plain  copy
  1. <span style="white-space:pre">          </span>//如果读操作成功的话,则返回0;如果读操作失败的话,则返回0xFF  
  2.                             if ( abort == 0 )  
  3.                             {  
  4.                                 MBXMEMCPY( ((TINITSDOUPLOADNORMRESMBX MBXMEM *) pSdoInd)->Data, pSdoSegData, dataSize );//将读到的pSdoSegData数据拷贝到pSdoInd的数据区。  
  5.                                 nSdoSegService    = SDOSERVICE_UPLOADSEGMENTREQ;  
  6.                             }  
  7. #if SDO_RES_INTERFACE  
  8.                             else if ( abort == ABORTIDX_WORKING )  
  9.                             {  
  10. /* ECATCHANGE_START(V5.01) SDO6*/  
  11.                                 /* the application generates the SDO-Response later on by calling SDOS_SdoRes (only possible if object access function pointer is defined) */  
[cpp]  view plain  copy
  1. //在这种情况应用程序产生一个SDO-Response通过调用函数SDOS_SdoRes()就是SDO响应程序,当数据对象接入函数已经被定义  
  2.                                 u8PendingSdo = SDO_PENDING_SEG_READ;  
  3.                                 bStoreCompleteAccess = bCompleteAccess;  
  4.                                 u8StoreSubindex = subindex;  
  5.                                 u16StoreIndex = index;  
  6.                                 u32StoreDataSize = objLength;  
  7.                                 pStoreData = pSdoSegData;  
  8.                                 pSdoPendFunc = pObjEntry->Read;//采用虚函数的形式定义数据对象的函数  
  9.   
  10.                                 bSdoInWork = TRUE;  
  11.                                 /* we have to store the buffer and the response header */  
  12.                                 pSdoResStored = pSdoInd;  
  13.   
  14.                                 /*update command field*/  
  15.                                 pSdoResStored->SdoHeader.Sdo[SDOHEADER_COMMANDOFFSET]   &= ~SDOHEADER_COMMANDMASK;  
  16.                                 pSdoResStored->SdoHeader.Sdo[SDOHEADER_COMMANDOFFSET]   |= (sdoHeader & (SDOHEADER_COMPLETEACCESS | SDOHEADER_COMMAND));  
  17.                                 nSdoSegService    = SDOSERVICE_UPLOADSEGMENTREQ;  
  18.                                 return 0;//返回去函数,并且,通过SDOS_SdoRes()来操作数据对象  
  19. /* ECATCHANGE_END(V5.01) SDO6*/  
  20.                             }  
  21. #endif  
  22.                         }  
  23.                         else//如果命令是SDO下载命令,则将pSdoInd->Data里面的数据拷贝到pSdoSegData里面,并且,付对应的SdoSegService和对应的数据长度  
  24.                         {  
  25.                             /* Segmented Download */  
  26.                             MBXMEMCPY( pSdoSegData, ((TINITSDODOWNLOADNORMREQMBX MBXMEM *) pSdoInd)->Data, mbxSize-DOWNLOAD_NORM_REQ_SIZE );  
  27.                             nSdoSegService    = SDOSERVICE_DOWNLOADSEGMENTREQ;  
  28.                             dataSize = (mbxSize-DOWNLOAD_NORM_REQ_SIZE);  
  29.                         }  
  30.   
  31.                         nSdoSegBytesToHandle = dataSize;  
  32.                     }  
  33.                 }  
  34.                 else//接下来的这种情况,考虑不是分段传输的情况  
  35. #endif // SEGMENTED_SDO_SUPPORTED  
  36.                 {  
  37. #if SEGMENTED_SDO_SUPPORTED  
  38. #if SDO_RES_INTERFACE  
  39.                     if ( objLength == 0 )  
  40.                     {  
  41.                         /* the objLength is not known, therefore the variables for a possible segmented transfer 
  42.                             should be initialized */  
  43.                         nSdoSegIndex             = index;  
  44.                         nSdoSegSubindex         = subindex;  
  45.                         pSdoSegObjEntry        = pObjEntry;  
  46.                     }  
  47. #endif // SDO_RES_INTERFACE  
  48. #endif // SEGMENTED_SDO_SUPPORTED  
  49.                     if ( command == SDOSERVICE_INITIATEUPLOADREQ )//如果SDO服务是上传服务  
  50.                     {  
  51.                         /* Expedited or Normal Upload *///已经排除了分段上传,就剩下快速上传和普通上传模式  
  52.                         abort = OBJ_Read( index, subindex, objLength, pObjEntry, pData, bCompleteAccess );  
  53. #if SDO_RES_INTERFACE  
  54.                         if ( abort == ABORTIDX_WORKING )  
  55.                         {  
  56. /* ECATCHANGE_START(V5.01) SDO6*/  
  57.                             /* the application generates the SDO-Response later on by calling SDOS_SdoRes (only possible if object access function pointer is defined) *///同上的分段上传的情况  
  58.                             u8PendingSdo = SDO_PENDING_READ;  
  59.                             bStoreCompleteAccess = bCompleteAccess;  
  60.                             u8StoreSubindex = subindex;  
  61.                             u16StoreIndex = index;  
  62.                             u32StoreDataSize = objLength;  
  63.                             pStoreData = pData;  
  64.                             pSdoPendFunc = pObjEntry->Read;  
  65.   
  66.                             bSdoInWork = TRUE;  
  67.                             /* we have to store the buffer and the response header */  
  68.                             pSdoResStored = pSdoInd;  
  69.                               
  70.                             /*update command field*/  
  71.                             pSdoResStored->SdoHeader.Sdo[SDOHEADER_COMMANDOFFSET] &= ~SDOHEADER_COMMANDMASK;  
  72.                             pSdoResStored->SdoHeader.Sdo[SDOHEADER_COMMANDOFFSET]    |= (sdoHeader & (SDOHEADER_COMPLETEACCESS | SDOHEADER_COMMAND));  
  73.                             return 0;  
  74. /* ECATCHANGE_END(V5.01) SDO6*/  
  75.                         }  
  76. #endif // SDO_RES_INTERFACE  
  77.                     }  
  78.                     else  
  79.                     {  
  80.                         /* Expedited or Normal Download *///快速和普通下载模式  
  81.                         abort = OBJ_Write( index, subindex, dataSize, pObjEntry, pData, bCompleteAccess );  
  82. #if SDO_RES_INTERFACE  
  83.                         if ( abort == ABORTIDX_WORKING )  
  84.                         {  
  85. /* ECATCHANGE_START(V5.01) SDO6*/  
  86.                             /* the application generates the SDO-Response later on by calling SDOS_SdoRes (only possible if object access function pointer is defined) */  
  87.                             u8PendingSdo = SDO_PENDING_WRITE;  
  88.                             bStoreCompleteAccess = bCompleteAccess;  
  89.                             u8StoreSubindex = subindex;  
  90.                             u16StoreIndex = index;  
  91.                             u32StoreDataSize = dataSize;  
  92.                             pStoreData = pData;  
  93.                             pSdoPendFunc = pObjEntry->Write;  
  94.   
  95.                             bSdoInWork = TRUE;  
  96.                             /* we have to store the buffer and the response header */  
  97.                             pSdoResStored = pSdoInd;  
  98.   
  99.                             /*update command field*/  
  100.                             pSdoResStored->SdoHeader.Sdo[SDOHEADER_COMMANDOFFSET] &= ~SDOHEADER_COMMANDMASK;  
  101.                             pSdoResStored->SdoHeader.Sdo[SDOHEADER_COMMANDOFFSET]    |= (sdoHeader & (SDOHEADER_COMPLETEACCESS | SDOHEADER_COMMAND));  
  102.                             return 0;  
  103. /* ECATCHANGE_END(V5.01) SDO6*/  
  104.                         }  
  105. #endif // SDO_RES_INTERFACE  
  106.                     }  
  107.                 } /* else if ( objLength == 0 ) */  
  108.             } /* if ( abort == 0 ) */  
  109.   
  110.         }//endif 获得不到对应的对象字典的句柄  
  111.         else  
  112.         {  
  113.             abort = ABORTIDX_OBJECT_NOT_EXISTING;  
  114.         }  
  115.         break;  
  116.   
  117. #if SEGMENTED_SDO_SUPPORTED  
  118.     case SDOSERVICE_DOWNLOADSEGMENTREQ://当SDOSERVICE_DOWNLOADSEGMENTREQ和SDOSERVICE_UPLOADSEGMENTREQ产生时候一并在下面处理  
  119.     case SDOSERVICE_UPLOADSEGMENTREQ:  
  120.         if ( command == nSdoSegService )  
  121.         {  
  122.             if ( command == SDOSERVICE_DOWNLOADSEGMENTREQ )  
  123.                 abort = SdoDownloadSegmentInd( (TDOWNLOADSDOSEGREQMBX MBXMEM *) pSdoInd );  
[cpp]  view plain  copy
  1. <span style="white-space:pre">      </span>//这个函数将会被调用当下载SDO主站的分段请求服务,如果它是最后一个分段数据的话,将会被写入到对象字典,这个函数自身会做出对象响应  
  2.             else  
  3.                 abort = SdoUploadSegmentInd( (TUPLOADSDOSEGREQMBX MBXMEM *) pSdoInd );  
  4.         }  
  5.         else  
  6.             abort = ABORTIDX_COMMAND_SPECIFIER_UNKNOWN;  
  7.         break;  
  8.   
  9. #endif  
  10.     default:  
  11.         abort = ABORTIDX_COMMAND_SPECIFIER_UNKNOWN;  
  12.         break;  
  13.     }  
  14.   
  15. #if SDO_RES_INTERFACE  
  16. /* ECATCHANGE_START(V5.01) SDO6*/  
  17.     if(abort != ABORTIDX_WORKING)  
  18. /* ECATCHANGE_END(V5.01) SDO6*/  
  19. #endif  
  20.     {  
  21.         /*当SDO响应应该被发送的时候,这个函数将会被调用*/  
  22.         SdoRes(abort, command, (UINT8) (sdoHeader & SDOHEADER_COMPLETEACCESS), (UINT16) dataSize, objLength, pSdoInd);  
  23.     }  
  24.   
  25.     return 0;  
  26. }  
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值