主题中讨论的其他器件:TCAN4550、 SysConfig
工具/软件:
大家好!
通过 SPI 对 TCAN455X 使用 simplelink_cc13xx_cc26xx_SDK_7_40_00_77可以驱动程序
我们在接收消息时遇到了问题:收到的消息经常会被复制,很少会丢失。
我的意思是"重复"是指 TCAN455X_taskFxn ()通过 TCAN455X_handleRxFIFO ()从 RX FIFO 两次读取同一条消息。
CAN 分析器显示该消息仅在总线上发送一次、因此必须在芯片或其驱动程序中进行复制。
更仔细地看 TCAN455X_handleRxFIFO ():
static void TCAN455X_handleRxFIFO(CAN_Handle handle, uint32_t fifoNum) { CAN_Object *object = (CAN_Object *)handle->object; MCAN_RxFIFOStatus fifoStatus = {0}; MCAN_getRxFIFOStatus(fifoNum, &fifoStatus); if ((fifoStatus.fillLvl > 0U) && !TCAN455X_isRxStructRingBufFull(handle)) { MCAN_readRxMsg(MCAN_MEM_TYPE_FIFO, fifoNum, &rxElem); /* Return value can be ignored since ring buffer is not full */ (void)StructRingBuf_put(&object->rxStructRingBuf, &rxElem); fifoStatus.fillLvl--; while ((fifoStatus.fillLvl > 0U) && !TCAN455X_isRxStructRingBufFull(handle)) { MCAN_readRxMsg(MCAN_MEM_TYPE_FIFO, fifoNum, &rxElem); /* Return value can be ignored since ring buffer is not full */ (void)StructRingBuf_put(&object->rxStructRingBuf, &rxElem); fifoStatus.fillLvl--; fifoStatus.getIdx++; /* Check for rollover */ if (fifoStatus.getIdx >= object->rxFIFONum[fifoNum]) { fifoStatus.getIdx = 0U; } } } /* Return value can be ignored since the inputs are known to be valid */ (void)MCAN_setRxFIFOAck(fifoNum, fifoStatus.getIdx); }
我们看到了2个潜在问题:
1.调用 MCAN_setRxFIFOCK()、即使消息未从 FIFO 中读取、因为 if 子句中的 TCAN455X_isRxStructRingBufull()、即默默地丢弃消息。 这是有意的吗?
2. 即使读取了多条消息、也只调用一次 MCAN_setRxFIFOCK()。 当索引在 while 循环中回滚时、这似乎不起作用。
我们现在修改了 TCAN455X_handleRxFIFO()、以便在阅读后立即对每条消息进行确认、这似乎已经解决了问题:
(删除 if 子句、保留 while 循环、并将 MCAN_setRxFIFOAck ()移入循环)
static void TCAN455X_handleRxFIFO(CAN_Handle handle, uint32_t fifoNum) { CAN_Object *object = (CAN_Object *)handle->object; MCAN_RxFIFOStatus fifoStatus = {0}; MCAN_getRxFIFOStatus(fifoNum, &fifoStatus); while ((fifoStatus.fillLvl > 0U) && !TCAN455X_isRxStructRingBufFull(handle)) { MCAN_readRxMsg(MCAN_MEM_TYPE_FIFO, fifoNum, &rxElem); /* Return value can be ignored since ring buffer is not full */ (void)StructRingBuf_put(&object->rxStructRingBuf, &rxElem); /* Return value can be ignored since the inputs are known to be valid */ (void)MCAN_setRxFIFOAck(fifoNum, fifoStatus.getIdx); fifoStatus.fillLvl--; fifoStatus.getIdx++; /* Check for rollover */ if (fifoStatus.getIdx >= object->rxFIFONum[fifoNum]) { fifoStatus.getIdx = 0U; } } }
由于额外的 ACK、fillLvl > 1时可能会造成性能损失、但 OTOH 我们现在会提前确认、因此 TCAN4550可以立即重新使用 FIFO 位置。 这极大地降低了最大 观察到的文件级别
这里的部分问题是 TCAN455X+MCAN+SPI 驱动程序效率非常低、无法以500kbit/s 的高总线负载接收所有消息:大约需要450µs 来处理1条 Rx 消息、但总线可以每个200µs 传输一条消息、即很容易地溢出 TCAN455X 驱动程序。
此致、
Wolfgang