Table of Contents |
---|
Background
As mandatory element, each EtherCAT slave has a slave information interface (SII) which is accessible by the master.
...
Please find more informations about the SII in the EtherCAT Slave Protocol API:
https://kbhilscher.hilscheratlassian.comnet/wiki/display/DL/EtherCAT+Slave
Create an SII image
With the help of the Conformance Test Tool (CTT) or TwinCAT, an SII image can be created from an ESI file.
...
- Open the Conformance Test Tool.
- Scan for any device and open the SII tab.
- Select the ESI file from the tab on the right side "ESI Files Repository" and add it to the SII tab via drag and drop.
- This can be saved in a *.BIN file now.
- Open the *.BIN file in an Hexeditior.
- Delete every entry before address 0x080 (first 128 bytes). This area will we written by the stack and is therefore not needed.
- change the *.BIN file to a *.c formatted file.
Write the SII image
The follow process needs to be performed, between the Channel Init state and "Bus on".
...
After getting the configuration "RCX_CHANNEL_INIT_CNF", call the function "Sii_SetupCategoryData()".
Code snippet LOM
Code Block |
---|
const TLR_UINT8 g_abSiiCategoryData []= { 0x0A, 0x00, 0x94, 0x00, … /*Please copy the data from the SII which has been created out of the ESI file here. Remember not to use the first 128 Byte!*/ }; const unsigned long g_ulSiiCategoryDataSize = sizeof(g_abSiiCategoryData); /******************************************************************************* * @brief This function creates a valid SII image for the slave. * It uses packets to copy the binary image of the category data into * the SII. * * @param ptRsc pointer to resources. * @param pbCategoryData pointer to image of category data according * to EtherCAT specification. * @param ulCategoryDataBytelen byte length of category data array * * @return TLR_RESULT returns TLR_S_OK if no error, * otherwise it will return an error code. */ TLR_RESULT Sii_SetupCategoryData( ECSPX_RSC_T* ptRsc, const TLR_UINT8* pbCategoryData, TLR_UINT32 ulCategoryDataBytelen) { TLR_RESULT eRslt = TLR_S_OK; ECAT_ESM_SII_WRITE_REQ_T* ptSiiWriteReq = NULL; void* pvPck = NULL; TLR_UINT32 ulImagePos = 0; TLR_UINT32 ulFragmentLen = 0; /* we start at position 0 of the image */ ulImagePos = 0x00; while (ulImagePos < ulCategoryDataBytelen) { /* by default we write 0x10 byte fragments */ ulFragmentLen = 0x10; /* check if our end position is larger than the image of the category data */ if (ulImagePos + ulFragmentLen > ulCategoryDataBytelen) { ulFragmentLen = ulCategoryDataBytelen - ulImagePos; } /* retrieve a pointer to a resource (packet) of pool */ eRslt = TLR_POOL_PACKET_GET(ptRsc->tLoc.hPool, &pvPck); if (eRslt != TLR_S_OK) { /* leave loop */ break; /* TODO: improve */ } /* write the fragment */ ptSiiWriteReq = (ECAT_ESM_SII_WRITE_REQ_T*)pvPck; memset(ptSiiWriteReq, 0, sizeof(ECAT_ESM_SII_WRITE_REQ_T)); /* fill packet header */ ptSiiWriteReq->tHead.ulDest = (UINT32)ptRsc->tRem.tEcsEsmTaskQueLink.hQue; ptSiiWriteReq->tHead.ulSrc = (UINT32)ptRsc->tLoc.hQue; ptSiiWriteReq->tHead.ulDestId = 0x00; ptSiiWriteReq->tHead.ulSrcId = 0x00; ptSiiWriteReq->tHead.ulLen = 4 + ulFragmentLen; ptSiiWriteReq->tHead.ulId = 0x00; ptSiiWriteReq->tHead.ulSta = TLR_S_OK; ptSiiWriteReq->tHead.ulCmd = ECAT_ESM_SII_WRITE_REQ; ptSiiWriteReq->tHead.ulExt = 0x00; ptSiiWriteReq->tHead.ulRout = 0x00; /* fill data part of packet */ ptSiiWriteReq->tData.ulOffset = ulImagePos + 0x80; /* category data starts at 0x80 of SII */ memcpy((char*)(&ptSiiWriteReq->tData.abData), pbCategoryData + ulImagePos, ulFragmentLen); /* fire the request */ eRslt = TLR_QUE_SENDPACKET_FIFO_INTERN(ptRsc->tRem.tEcsEsmTaskQueLink.hQue, ptSiiWriteReq, TLR_INFINITE); /* TODO: TLR_QUE_SENDPACKET_FIFO */ /* TODO: why not TLR_FINITE ? */ if ( eRslt != TLR_S_OK ) { eRslt = TLR_POOL_PACKET_RELEASE( ptRsc->tLoc.hPool, ptSiiWriteReq ); /* leave loop */ break; } /* we wait directly for expected cnf packet */ eRslt = WaitForResponse( ptRsc, (ptSiiWriteReq->tHead.ulCmd | 1) ); /* TODO: improve !! */ if ( eRslt != TLR_S_OK ) { /* leave loop */ break; /* TODO: improve ? */ } /* set next start position */ ulImagePos += ulFragmentLen; } /* check if error occured */ if ( eRslt != TLR_S_OK ) { TODO: add error handling */ } return eRslt; } |
Change the LOM Codesnippet to fit the CIFX API
The paket send function needs to be changed as shown below for use in CIFX API, sind the above code-snippet has been created for LOM Firmware only.
...