你(们)好!
我在 EtherCAT 子器件堆栈和缓冲区处理 API 方面遇到了另一个问题。
我正在使用:
-来自 TI/Kunbus 的 EtherCAT 子器件堆栈
-工业通信 SDK 09.01. 版本
我正在使用以下堆栈函数来重新设置调用者的回调
EC_API_SLV_cbRegisterPreSeqInputPDBuffer (...);
EC_API_SLV_cbRegisterPostSeqInputPDBuffer (...);
EC_API_SLV_cbRegisterPreSeqOutputPDBuffer (...);
EC_API_SLV_cbRegisterPostSeqOutputPDBuffer (...);
不过、这些回调不会获取正确的位长度。 位长度似乎是互换的。 我在 InputPDBuffer 回调中获取 OutputPDBuffer 的位长度、反之亦然。
我使用09_01_00_00_ethercat_slave_simple_demo_am243x-evm_r5fss0-0_freertos_ti-arm-clang 示例复制了该行为。 我添加了另一个32位大小的 RX-PDO。 此后、我确定了 RX-PDO 大小(96位)和 TX-PDO 大小(64位)。
我还 修改由 EC_API_SLV_cbRegisterPreSeqInputPDBuffer (...)注册的函数中的数据 因此、我可以确保 InputPDBuffer-callback 应请求我们发送到 SPS 的数据、因为我成功地以 SPS 的形式接收了该数据。 不过、给定的大小是错误的。 在 InputPDBuffer-callback 中、我获取了96位的位大小。
另请参阅以下补丁、它清楚地显示了我在示例中更改的内容:
diff --git a/ecSlvSimple.c b/ecSlvSimple.c
index 7670305..319c19b 100644
--- a/ecSlvSimple.c
+++ b/ecSlvSimple.c
@@ -2146,6 +2146,36 @@ static EC_API_EError_t EC_SLV_APP_SS_populateRxPDO(EC_SLV_APP_SS_Application_t*
goto Exit;
}
+ EC_API_SLV_Pdo_t* ptRxPdo1602 = NULL;
+
+ error = (EC_API_EError_t)EC_API_SLV_PDO_create(ptSlave, "RxPDO3", 0x1602, &ptRxPdo1602);
+ if (error != EC_API_eERR_NONE)
+ {
+ OSAL_printf("Create PDO 0x1601 Error code: 0x%08x\r\n", error);
+ /* @cppcheck_justify{misra-c2012-15.1} goto is used to assure single point of exit */
+ /* cppcheck-suppress misra-c2012-15.1 */
+ goto Exit;
+ }
+ OSAL_printf("RxPDO created 0x1602: 0x%lx\r\n", (uint32_t)ptRxPdo1602);
+
+ error = (EC_API_EError_t)EC_API_SLV_CoE_getObjectEntry(ptSlave, 0x2000, 1, &ptObjEntry);
+ if (error != EC_API_eERR_NONE)
+ {
+ OSAL_printf("%s:%d Variable Error code: 0x%08x\r\n", __func__, __LINE__, error);
+ /* @cppcheck_justify{misra-c2012-15.1} goto is used to assure single point of exit */
+ /* cppcheck-suppress misra-c2012-15.1 */
+ goto Exit;
+ }
+
+ error = (EC_API_EError_t)EC_API_SLV_PDO_createEntry(ptSlave, ptRxPdo1602, "SubIndex 001", ptObjEntry);
+ if (error != EC_API_eERR_NONE)
+ {
+ OSAL_printf("%s:%d Variable Error code: 0x%08x\r\n", __func__, __LINE__, error);
+ /* @cppcheck_justify{misra-c2012-15.1} goto is used to assure single point of exit */
+ /* cppcheck-suppress misra-c2012-15.1 */
+ goto Exit;
+ }
+
error = EC_API_eERR_NONE;
Exit:
return error;
@@ -2930,6 +2960,48 @@ static bool EC_SLV_APP_EoE_SS_receiveHandler(void* pContext_p, uint16_t* pData_p
return true;
}
+static uint8_t data_tx[1024]={0};
+
+static void*acquireTxBuffer(void* pContext_p, uint32_t length_p)
+{
+ static int counter = 0;
+ if(counter >> 8)
+ {
+ OSAL_printf("tx length: %d\r\n", length_p);
+ counter = 0;
+ }
+ counter++;
+
+ data_tx[0]++;
+ data_tx[1]++;
+ data_tx[2]++;
+ data_tx[3]++;
+ return &data_tx[0];
+}
+
+static void releaseTxBuffer(void* pContext_p, void* pData_p, uint32_t length_p)
+{
+ // nothing to do here just a test
+}
+
+static uint8_t data_rx[1024]={0};
+
+static void*acquireRxBuffer(void* pContext_p, uint32_t length_p)
+{
+ static int counter = 0;
+ if(counter >> 7)
+ {
+ OSAL_printf("rx length: %d\r\n", length_p);
+ counter = 0;
+ }
+ return &data_rx[0];
+}
+
+static void releaseRxBuffer(void* pContext_p, void* pData_p, uint32_t length_p)
+{
+ // nothing to do here just a test
+}
+
/*!
* <!-- Description: -->
*
@@ -3067,6 +3139,7 @@ void EC_SLV_APP_SS_applicationInit(EC_SLV_APP_SS_Application_t *pAppInstance_p)
}
/*PDO Mapping Changes*/
+ EC_API_SLV_PDO_setAssignment(pAppInstance_p->ptEcSlvApi, true);
EC_API_SLV_PDO_registerAssignmentChanges(pAppInstance_p->ptEcSlvApi, EC_SLAVE_APP_assignmentChangedHandler, pAppInstance_p);
EC_API_SLV_PDO_registerMappingChanges(pAppInstance_p->ptEcSlvApi, EC_SLAVE_APP_mappingChangedHandler, pAppInstance_p);
@@ -3088,7 +3161,9 @@ void EC_SLV_APP_SS_applicationInit(EC_SLV_APP_SS_Application_t *pAppInstance_p)
EC_API_SLV_DIAG_enable(pAppInstance_p->ptEcSlvApi);
#if !(defined DPRAM_REMOTE) && !(defined FBTL_REMOTE) && !(defined OSAL_FREERTOS_JACINTO) /* first omit flash */
- EC_API_SLV_cbRegisterFlashInit (pAppInstance_p->ptEcSlvApi, EC_SLV_APP_EEP_initFlash, pAppInstance_p->ptEcSlvApi);
+ // currently not supported for our custom board
+
+ // EC_API_SLV_cbRegisterFlashInit (pAppInstance_p->ptEcSlvApi, EC_SLV_APP_EEP_initFlash, pAppInstance_p->ptEcSlvApi);
/* @cppcheck_justify{misra-c2012-11.6} void cast required for signature */
/* cppcheck-suppress misra-c2012-11.6 */
EC_API_SLV_EEPROM_cbRegisterWrite (pAppInstance_p->ptEcSlvApi, EC_SLV_APP_EEP_writeEeprom, OSPIFLASH_APP_STARTMAGIC);
@@ -3098,6 +3173,12 @@ void EC_SLV_APP_SS_applicationInit(EC_SLV_APP_SS_Application_t *pAppInstance_p)
#endif
EC_API_SLV_cbRegisterUserApplicationRun (pAppInstance_p->ptEcSlvApi, EC_SLV_APP_SS_applicationRun, pAppInstance_p);
+ /* buffer callbacks */
+ EC_API_SLV_cbRegisterPreSeqInputPDBuffer(pAppInstance_p->ptEcSlvApi, acquireTxBuffer, pAppInstance_p->ptEcSlvApi);
+ EC_API_SLV_cbRegisterPostSeqInputPDBuffer(pAppInstance_p->ptEcSlvApi, releaseTxBuffer, pAppInstance_p->ptEcSlvApi);
+ EC_API_SLV_cbRegisterPreSeqOutputPDBuffer(pAppInstance_p->ptEcSlvApi, acquireRxBuffer, pAppInstance_p->ptEcSlvApi);
+ EC_API_SLV_cbRegisterPostSeqOutputPDBuffer(pAppInstance_p->ptEcSlvApi, releaseRxBuffer, pAppInstance_p->ptEcSlvApi);
+
error = (EC_API_EError_t)EC_API_SLV_init(pAppInstance_p->ptEcSlvApi);
if (error != EC_API_eERR_NONE)
{
@@ -3350,6 +3431,9 @@ static void EC_SLV_APP_SS_applicationRun(void* pAppCtxt_p)
}
#if !(defined FBTL_REMOTE) || (0 == FBTL_REMOTE)
+#if 0
+ // I don't use this code, as processdata is updated via callbacks only
+
err = (EC_API_EError_t)EC_API_SLV_PDO_setEntryData(pApplicationInstace->ptEcSlvApi
,pApplicationInstace->ptTxPdo1A00
,1
@@ -3359,6 +3443,7 @@ static void EC_SLV_APP_SS_applicationRun(void* pAppCtxt_p)
{
OSAL_printf("Fill Description Object Error code: 0x%08x\r\n", err);
}
+#endif
#endif
}
else
@@ -3394,6 +3479,9 @@ static void EC_SLV_APP_SS_applicationRun(void* pAppCtxt_p)
lastLed = (lastLed << 1u);
}
+#if 0
+ // I don't use this code, as processdata is updated via callbacks only
+
//Write Led data to the process data. It can be seen in OBD in Object 0x2002:2 as well.
error = EC_API_SLV_PDO_setEntryData(
pApplicationInstace->ptEcSlvApi,
@@ -3406,6 +3494,7 @@ static void EC_SLV_APP_SS_applicationRun(void* pAppCtxt_p)
{
OSAL_printf("%s:%d:E=0x%x\r\n", __func__, __LINE__, error);
}
+#endif
}
}
PS:我认为以下是正确的:
-输入数据=>从子设备发送数据-> SPS
-输出数据=>从 SPS 发送数据->子设备
-输入数据== TX 数据
-输出数据== RX 数据