工具与软件:
您好!
我正在尝试通过 EtherCAT 获取 CAN、以便将工业 SDK 09.00.00.03与 SOE EtherCAT 堆栈结合使用、在 AM6442-EVM 开发套件上运行。 与 TI 的 BSP 代码集成取自 am335示例。 到目前为止、堆栈进入 OP 模式。 当主器件预期进行 PDO 通信时、问题就会开始。
第一个问题是使 SOE 注册为存在 PDO 通信。 PSE 未正确检测 ALEvent 寄存器状态。 但日志记录确实显示 ALEVENTMASK 已正确设置。 在此片段中:
/** ESC interrupt enable function by the Slave stack in IRQ mode.
*
* @param[in] mask = of interrupts to enable
*/
void ESC_interrupt_enable(uint32_t mask)
{
DebugP_log("Enabling interrupts: '%X'\r\n", mask);
print_present_mask_bits(mask);
const uint32_t readmask = bsp_read_dword_isr(escHwPruIcssHandle, ESCREG_ALEVENTMASK);
DebugP_log("Already present interrupts are: '%X'\r\n", readmask);
print_present_mask_bits(readmask);
bsp_write_dword(escHwPruIcssHandle, (mask | readmask), ESCREG_ALEVENTMASK);
}
将记录以下内容:
Enabling interrupts: '400' Bit 'ALEVENT_SM2' is present. Already present interrupts are: 'FFF32B' Bit 'ALEVENT_CONTROL' is present. Bit 'ALEVENT_DC_LATCH' is present. Bit 'ALEVENT_DC_SYNC1' is present. Bit 'ALEVENT_EEP' is present. Bit 'ALEVENT_SM0' is present. Bit 'ALEVENT_SM1' is present.
以确保器件从 PREOP 切换到 SAFeOP。
如果我正确理解、在第一个代码片段中通过"bsp_write_dword"启用中断应该会触发 PRUICSS_waitEvent (pruIcss1Handle、host_AL_event - 20)调用上的唤醒。 相应地应在 SOE 中调用 PDI_ISR()、该 SOE 应更新 ALEvent、如以下代码片段所示:
/** PDI ISR handler
*
* @param[in] arg = NOT USED
*/
void PDI_Isr(void)
{
uint16_t alevent;
alevent = bsp_read_word_isr(escHwPruIcssHandle, ESCREG_ALEVENT);
CC_ATOMIC_SET(ESCvar.ALevent, etohs(alevent));
if (ESCvar.ALevent & (ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3))
{
DIG_process(DIG_PROCESS_OUTPUTS_FLAG |
DIG_PROCESS_APP_HOOK_FLAG |
DIG_PROCESS_INPUTS_FLAG);
}
}
这里的问题是 ALevent 的值从不设置'ESCRG_ALEVENT_SM2'位。 如果我正确理解、以下哪一项是从主器件接收到的 PDO 通信的事件...? 未获得此事件意味着不使用来自主器件的 PDO 信息更新从器件。 这会导致例如电机状态字保持"不工作"状态、因为主器件无法通过从器件的 RXPDO 将电机更改为更工作的状态。
解决方法强制发生 SM2事件。 以查看通信控制流程的其余部分是否正常工作。 这也是 PDO 通信中的另一个问题、其中 process-data-buffer 的基地址在以下代码片段中移动:
static void ESC_readRXPDO(uint8_t *pData, uint16_t Address, uint16_t Len)
{
int16_t sm_index;
uint16_t ActAddress = bsp_get_process_data_address(escHwPruIcssHandle, Address, Len,
&sm_index);
// Correct the actualAddr. As it induces an offset.
// ActAddress = Address;
if (ActAddress < ESC_ADDR_MEMORY)
{
pd_read_addr_err++;
return;
}
bsp_read(escHwPruIcssHandle, pData, ActAddress, Len);
bsp_process_data_access_complete(escHwPruIcssHandle, Address, Len, sm_index);
}
而无需还原"ActAddress"。 缓冲区起始地址从其 ESI 定义的位置移位:
0x1800 -> 0x1809
我不明白为什么会发生这种情况。 在下面的位置、当 SOE 开始刷新 RXPDO 时、还会导致数据无法读取:
/** Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update (void)
{
if(ESCvar.rxpdo_override != NULL)
{
(ESCvar.rxpdo_override)();
}
else
{
ESC_read (ESC_SM2_sma, rxpdo, ESCvar.ESC_SM2_sml);
if (MAX_MAPPINGS_SM2 > 0)
{
COE_pdoUnpack (rxpdo, ESCvar.sm2mappings, SMmap2);
}
}
}
无需还原'ESC_readRXPDO'代码片段中的地址、上述代码片段中提供的'rxpdo'数组就会保持空状态。 虽然、如果"bsp_get_process_data_address"返回的地址 恢复为 ESI 地址、则缓冲区会包含正确的数据、该数据会传递到我们的对象字典、从而更新电机的控制字并将其传递到工作模式。
我的问题是、这里出现了什么问题、导致 SyncManager 事件不发生;以及 RXPDO 通信失败? 我在哪里可以阅读有关同步管理器配置过程以正确进行此 PDO 通信的更多信息? 我确实检查了 ETG 规范、但找不到有关此缓冲器配置应如何工作/排列的参考。
此致、
Matthijs