这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K3XX】FlexCAN MB 报文发送流程代码梳理

共4条 1/1 1 跳转至

【S32K3XX】FlexCAN MB 报文发送流程代码梳理

高工
2026-07-29 08:05:32     打赏

【简介】

在之前的贴子中我们已经对S32K3 的CAN 模块做了些如下介绍:

【S32K3XX】FlexCAN RAM 资源分配整理

【S32K3XX】FlexCAN 模块配置使用

【S32K3XX】FlexCAN MB 发送状态机机制

今天我们继续结合S32K 的RM手册和RTD的驱动代码梳理下CAN 模块报文发送的流程,以下是K3 的RM文档中对CAN 消息发送流程的说明。

image.png

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

image.png

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

image.png

上述流程的 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 的中断信号。

image.png

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


           


专家
2026-07-29 08:26:54     打赏
2楼

谢谢楼主分享


助工
2026-07-30 10:16:22     打赏
3楼

又是枯燥的英文字母。


助工
2026-07-30 10:24:55     打赏
4楼

车规芯片对CAN通讯的支持一定是不一样的吧?

比如和STM32F103


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]