主题中讨论的其他器件: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