This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AWR1642:有关 CAN FD 模块中发送完成中断处理的问题

Guru**** 2604225 points
Other Parts Discussed in Thread: AWR1642, AWR1642BOOST

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/sensors-group/sensors/f/sensors-forum/658761/awr1642-questions-about-the-processing-in-transmit-complete-interrupt-in-can-fd-module

器件型号:AWR1642

您好!

我正在 验证 MMWAVE_SDK_01_01_00_02中的 CAN FD 驱动程序。   我对传输完成中断有疑问。

在函数"static void CANFD_MCANInt0Isr (uintptr_t arg)"中、已完成传输的 TX 缓冲器由寄存器 MCAN_TXBTO 的状态判断、并将调用已注册的回调。 但是 、在 ISR 函数 CANFD_MCANInt0Isr 中、寄存器 MCAN_TXBTO 未复位。 因此、当 CANFD_MCANInt0Isr 再次触发时、将多次调用回调。 因此、不能使用回调函数来计数已传输的数据包数量。 这是正确的,还是可以提供其他方法来计数成功传输的数据包? 此外、当寄存器 MCAN_TXBTO 在初始化之后将被复位时。

以下是 CANFD_MCANInt0Isr 的源代码、也可以在 packages/ti\drivers\canfd\src\canfd.c 中找到

祝你一切顺利、

Beren

/**
*@b 说明
*@n
* 该函数是 CANFD 驱动程序的寄存中断0 ISR。
*
*@param[in] arg
* 注册 ISR 时在操作系统中注册的参数
*
*\ingroup CANFD_DRIVER_INTERNAL_FUNCTION
*
*@retval
* 不适用
*/
静态空 CANFD_MCANInt0Isr (uintptr_t arg)
{
CANFD_MessageObject* ptrCanMsgObj;
CANFD_DriverMCB* ptrCanFdMCB;
uint32_t baseAddr;
uint32_t 内部状态;
uint32_t index、status、buffIndex;
MCAN_RxNewDataStatus newDataStatus;

/*获取 CAN 驱动程序块的指针*/
ptrCanFdMCB =(CANFD_DriverMCB*)参数;

/*递增接收到的中断数*/
ptrCanFdMCB->Interrupts++;
baseAddr = ptrCanFdMCB->hwcfg.regBaseAddress;

intrStatus = MCAN_getIntraStatus (baseAddr);
MCAN_clearIntStatus (baseAddr、intrStatus);

/*处理总线关闭条件*/
IF (((内部状态和 MCAN_INTR_SRC_BUS_OFF_STATUS)== MCAN_INTR_SRC_BUS_OFF_STATUS)
{
/*递增接收到的中断数*/
ptrCanFdMCB->busOffInterrupts++;

ptrCanFdMCB->state = CANFD_DriverState_Stopped;

/*呼叫注册的回叫。 *
if (ptrCanFdMCB->appErrCallBack!=空)
{
ptrCanFdMCB->appErrCallBack ((CANFD_Handle) ptrCanFdMCB、CANFD_REASE_BUSOFF、NULL);
}
}

/*数据阶段条件中的处理协议错误*/
IF (((内部状态和 MCAN_INTR_SRC_PROTOCOL_ERR_DATA)== MCAN_INTR_SRC_PROTOCOL_ERR_DATA)
{
/*递增接收到的中断数*/
ptrCanFdMCB->protoDataErrInterrupts++;

/*呼叫注册的回叫。 *
if (ptrCanFdMCB->appErrCallBack!=空)
{
ptrCanFdMCB->appErrCallBack ((CANFD_Handle) ptrCanFdMCB、CANFD_REASE_PROTOCOL_ERR_DATA_PHASE、NULL);
}
}

/*仲裁阶段条件中的处理协议错误*/
IF (((内部状态和 MCAN_INTR_SRC_PROTOCOL_ERR_ARB)== MCAN_INTR_SRC_PROTOCOL_ERR_ARB)
{
/*递增接收到的中断数*/
ptrCanFdMCB->ProtoArb 勘误中断++;

/*呼叫注册的回叫。 *
if (ptrCanFdMCB->appErrCallBack!=空)
{
ptrCanFdMCB->appErrCallBack ((CANFD_Handle) ptrCanFdMCB、CANFD_REASE_PROTOCOL_ERR_ARB_PHASE、NULL);
}
}

/*进程传输完成中断*/
IF (((内部状态和 MCAN_INTR_SRC_TRANS_COMPLETE)=MCAN_INTR_SRC_TRANS_COMPLETE)
{
状态= MCAN_getTxBufTransmissionStatus (baseAddr);

/*处理所有32个 Tx 缓冲器*/
for (索引= 0;索引< MCAN_MAX_TX_BUFFERS;索引++)
{
buffIndex =((uint32_t) 1U <<索引);
if (buffIndex ==(status & buffIndex))
{
/*获取消息对象指针*/
ptrCanMsgObj = ptrCanFdMCB->txMapping[索引];

/*递增接收到的中断数*/
ptrCanMsgObj->interrtsRxed++;

/*呼叫注册的回叫。 *
if (ptrCanFdMCB->appDataCallBack!=空)
{
ptrCanFdMCB->appDataCallBack ((CANFD_MsgObjHandle) ptrCanMsgObj、CANFD_REASE_TX_Completion);
}
}
STATUS =(STATUS &μ~buffIndex);
如果(状态= 0)
{
中断;
}
}


/*进程接收中断*/
if (((状态中和 MCAN_INTR_SRC_Dedicated RX_buff)== MCAN_INTR_SRC_Deded_RX_buff)
{
/*获取新数据状态*/
MCAN_getNewDataStatus (baseAddr、&newDataStatus);

/*清除 NewData 状态以接受新消息*/
MCAN_clearNewDataStatus (baseAddr、&newDataStatus);

/*处理所有64个 Rx 缓冲器*/
for (索引= 0;索引< MCAN_MAX_RX_BUFFERS;索引++)
{
if (索引< 32U)
{
status = newDataStatus.statusLow;
buffIndex =(uint32_t) 1U <<索引;
}
其他
{
status = newDataStatus.statusHigh;
buffIndex =(uint32_t) 1U <<(索引- 32U);
}

if (buffIndex ==(status & buffIndex))
{
/*获取消息对象指针*/
ptrCanMsgObj = ptrCanFdMCB->rxMapping[索引];

/*递增接收到的中断数*/
ptrCanMsgObj->interrtsRxed++;

/*呼叫注册的回叫。 *
if (ptrCanFdMCB->appDataCallBack!=空)
{
ptrCanFdMCB->appDataCallBack ((CANFD_MsgObjHandle) ptrCanMsgObj、CANFD_reason_RX);
}
}

}

/*进程传输取消中断*/
IF (((内部状态和 MCAN_INTR_SRC_TRANS_CANCELL_FINISH)== MCAN_INTR_SRC_TRANS_CANCEL_FINISH)
{
status = MCAN_txBufCancellationStatus (baseAddr);

/*处理所有32个 Tx 缓冲器*/
for (索引= 0;索引< MCAN_MAX_TX_BUFFERS;索引++)
{
buffIndex =((uint32_t) 1U <<索引);
if (buffIndex ==(status & buffIndex))
{
/*获取消息对象指针*/
ptrCanMsgObj = ptrCanFdMCB->txMapping[索引];

/*递增接收到的中断数*/
ptrCanMsgObj->interrtsRxed++;

/*呼叫注册的回叫。 *
if (ptrCanFdMCB->appDataCallBack!=空)
{
ptrCanFdMCB->appDataCallBack ((CANFD_MsgObjHandle) ptrCanMsgObj、CANFD_reason_TX_Canceled);
}
}
STATUS =(STATUS &μ~buffIndex);
如果(状态= 0)
{
中断;
}
}


返回;
} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Lei Chen,

    "MCAN_TXBTO"寄存器是一个"只读"寄存器、用户不能对该寄存器进行写操作。 这就是在 不同任务/线程中完成和维护已发送消息计数的原因。

    寄存器信息可在"21.3.1.67  MCAN_TXBTO 寄存器(偏移= 2D8h)"部分的 AWR1642 TRM 中找到。

    希望这能澄清您的疑问。

    谢谢、

    Raghu

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Raghu、

    感谢您的回复。 但我仍然怀疑 appDataCallBack 将在一个中断中被多次触发。

    在 CANFD_MCANInt0Isr 中处理发送完成中断期间、将检查所有32个 TX 缓冲区和 MCAN_TXBTO 中的所有32位、如果 MCAN_TXBTO 中的第 n 位不为零、则将处理第 n 个 TX 缓冲区、例如、将调用 appDataCallBack。

    例如、如果创建了两个 CANFD 报文对象来发送两条报文。 发送第一条消息时、将触发 ISR 函数 CANFD_MCANInt0Isr、因为 MCAN_TXBTO 中的第一个位不为零、因此将调用第一个消息对象的回调函数 appDataCallBack。 但是、当第二次触发时、ISR 函数 CANFD_MCANInt0Isr 将再次触发、因为 MCAN_TXBTO 中的第一个位和第二个位都不为零、因此将首先调用第一个消息对象的回调函数 appDataCallBack、 第二个消息对象的回调函数将被调用。 因此、在传输两条消息时、第一个按摩对象的回调将被调用两次、第二个按摩对象的回调将被调用一次。

    以下是在 CANFD_MCANInt0Isr 中处理发送完成中断的代码。

    祝你一切顺利、

    Beren

    /*进程传输完成中断*/
    IF (((内部状态和 MCAN_INTR_SRC_TRANS_COMPLETE)=MCAN_INTR_SRC_TRANS_COMPLETE)
    {
    状态= MCAN_getTxBufTransmissionStatus (baseAddr);
    
    /*处理所有32个 Tx 缓冲器*/
    for (索引= 0;索引< MCAN_MAX_TX_BUFFERS;索引++)
    {
    buffIndex =((uint32_t) 1U <<索引);
    if (buffIndex ==(status & buffIndex))
    {
    /*获取消息对象指针*/
    ptrCanMsgObj = ptrCanFdMCB->txMapping[索引];
    
    /*递增接收到的中断数*/
    ptrCanMsgObj->interrtsRxed++;
    
    /*呼叫注册的回叫。 *
    if (ptrCanFdMCB->appDataCallBack!=空)
    {
    ptrCanFdMCB->appDataCallBack ((CANFD_MsgObjHandle) ptrCanMsgObj、CANFD_REASE_TX_Completion);
    }
    }
    STATUS =(STATUS &μ~buffIndex);
    如果(状态= 0)
    {
    中断;
    }
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好,Lei Chen,

    在我的设置中、我看不到 appCallback 被多次触发。 我修改了 CANFD 驱动程序应用程序以发送128字节,并看到 appCallback 被称为16次(128/8= 16:经典 CAN 模式)

    您的 CAN 总线上是否有多个 CAN 节点或只有一个传感器(AWR1642BOOST)?

    -Raghu