【简介】
在之前的贴子中我们已经对S32K3 的CAN 模块做了些如下介绍:
今天我们继续结合S32K 的RM手册和RTD的驱动代码梳理下CAN 模块报文发送的流程,以下是K3 的RM文档中对CAN 消息发送流程的说明。

上述流程在发送CAN 消息时,首先需要检查MB的中断标志位,如果被设置需要清除对应的中断状态信号,以下代码对应清除中断的处理。

上述流程的 2/3/4/5 是确认MB 当前是否有 pending 的消息在发送,如果有则取消当前消息的发送,对应RTD的处理流程是当前MB如果是Busy 状态则返回本次发送失败。

上述流程的 6/7/8 主要是更新MB 的CS信息和 Payload 数据更新 从而完成数据的发送,对应代码如下:
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_SetTxMsgBuff
* Description : Configure a message buffer for transmission.
* This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
* the function will make sure if the MB requested is not occupied by RX FIFO
* and ID filter table. Then this function will copy user's buffer into the
* message buffer data area and configure the message buffer as required for
* transmission.
*
*END**************************************************************************/
void FlexCAN_SetTxMsgBuff(volatile uint32 * const pMbAddr,
const Flexcan_Ip_MsbuffCodeStatusType * Cs,
uint32 MsgId,
const uint8 * MsgData,
const boolean IsRemote
)
{
#if (FLEXCAN_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert((boolean)(Cs != NULL_PTR));
#endif
uint32 FlexcanMbConfig = 0;
uint8 DataByte;
uint8 DlcValue;
uint8 PayloadSize;
volatile uint32 * FlexcanMb = pMbAddr;
volatile uint32 * FlexcanMbId = &FlexcanMb[1];
volatile uint8 * FlexcanMbData = (volatile uint8*)(&FlexcanMb[2]);
volatile uint32 * FlexcanMbData32 = &FlexcanMb[2];
const uint32 * MsgData32 = (const uint32*)MsgData;
/* Clean up the arbitration field area and set TxMB Inactive */
*FlexcanMb = (uint32)((((uint32)FLEXCAN_TX_INACTIVE & (uint32)0x1F) << (uint8)FLEXCAN_IP_CS_CODE_SHIFT) & (uint32)FLEXCAN_IP_CS_CODE_MASK);
*FlexcanMbId = 0;
/* Compute the value of the DLC field */
DlcValue = FlexCAN_ComputeDLCValue(Cs->dataLen);
/* Copy user's buffer into the message buffer data area */
if (MsgData != NULL_PTR)
{
for (DataByte = 0; DataByte < (Cs->dataLen & ~3U); DataByte += 4U)
{
FLEXCAN_IP_SWAP_BYTES_IN_WORD((MsgData32[DataByte >> 2U]), (FlexcanMbData32[DataByte >> 2U]));
}
for ( ; DataByte < Cs->dataLen; DataByte++)
{
FlexcanMbData[FLEXCAN_IP_SWAP_BYTES_IN_WORD_INDEX(DataByte)] = MsgData[DataByte];
}
#if (FLEXCAN_IP_FEATURE_HAS_FD == STD_ON)
PayloadSize = FlexCAN_ComputePayloadSize(DlcValue);
/* Add padding, if needed */
for (DataByte = Cs->dataLen; DataByte < PayloadSize; DataByte++)
{
FlexcanMbData[FLEXCAN_IP_SWAP_BYTES_IN_WORD_INDEX(DataByte)] = Cs->fd_padding;
}
#endif /* FLEXCAN_IP_FEATURE_HAS_FD */
}
/* Set the ID according the format structure */
if (FLEXCAN_MSG_ID_EXT == Cs->msgIdType)
{
/* ID [28-0] */
*FlexcanMbId &= ~(FLEXCAN_IP_ID_STD_MASK | FLEXCAN_IP_ID_EXT_MASK);
*FlexcanMbId |= (MsgId & (FLEXCAN_IP_ID_STD_MASK | FLEXCAN_IP_ID_EXT_MASK));
/* Set IDE and SRR bit*/
FlexcanMbConfig |= (FLEXCAN_IP_CS_IDE_MASK | FLEXCAN_IP_CS_SRR_MASK);
}
if (FLEXCAN_MSG_ID_STD == Cs->msgIdType)
{
/* ID[28-18] */
*FlexcanMbId &= ~FLEXCAN_IP_ID_STD_MASK;
*FlexcanMbId |= (MsgId << FLEXCAN_IP_ID_STD_SHIFT) & FLEXCAN_IP_ID_STD_MASK;
/* make sure IDE and SRR are not set */
FlexcanMbConfig &= ~(FLEXCAN_IP_CS_IDE_MASK | FLEXCAN_IP_CS_SRR_MASK);
}
/* Set the length of data in bytes */
FlexcanMbConfig &= ~FLEXCAN_IP_CS_DLC_MASK;
FlexcanMbConfig |= ((uint32)DlcValue << FLEXCAN_IP_CS_DLC_SHIFT) & FLEXCAN_IP_CS_DLC_MASK;
/* Set MB CODE */
if (Cs->code != (uint32)FLEXCAN_TX_NOT_USED)
{
if ((uint32)FLEXCAN_TX_REMOTE == Cs->code)
{
/* Set RTR bit */
FlexcanMbConfig |= FLEXCAN_IP_CS_RTR_MASK;
}
else
{
if (TRUE == IsRemote)
{
/* Set RTR bit */
FlexcanMbConfig |= FLEXCAN_IP_CS_RTR_MASK;
}
}
/* Reset the code */
FlexcanMbConfig &= ~FLEXCAN_IP_CS_CODE_MASK;
/* Set the code */
if (Cs->fd_enable)
{
FlexcanMbConfig |= ((Cs->code << FLEXCAN_IP_CS_CODE_SHIFT) & FLEXCAN_IP_CS_CODE_MASK) | FLEXCAN_IP_MB_EDL_MASK;
/* In case of FD frame not supported RTR */
FlexcanMbConfig &= ~FLEXCAN_IP_CS_RTR_MASK;
}
else
{
FlexcanMbConfig |= (Cs->code << FLEXCAN_IP_CS_CODE_SHIFT) & FLEXCAN_IP_CS_CODE_MASK;
}
if (Cs->enable_brs)
{
FlexcanMbConfig |= FLEXCAN_IP_MB_BRS_MASK;
}
*FlexcanMb = FlexcanMbConfig;
}
} 上述配置完成后RTD驱动会使能MB 的中断信号。

对应CAN 报文发送完成后产生发送完成的中断事件从而完成CAN报文的发送处理。
我要赚赏金
