工具配置
基本就是默认配置就行,有需要的话就按照下面的方式改改。

生成代码
在Generated_Code/canCom1.c里面,对应刚才配置的信息。canCom1_InitConfig0是配置结构体,canCom1_State是初始化之后的状态结构体。
flexcan_state_t canCom1_State; 
const flexcan_user_config_t canCom1_InitConfig0 = {
    .fd_enable = false,
    .pe_clock = FLEXCAN_CLK_SOURCE_OSC,
    .max_num_mb = 32,
    .num_id_filters = FLEXCAN_RX_FIFO_ID_FILTERS_32,
    .is_rx_fifo_needed = true,
    .flexcanMode = FLEXCAN_NORMAL_MODE,
    .payload = FLEXCAN_PAYLOAD_SIZE_8,
    .bitrate = {
        .propSeg = 7,
        .phaseSeg1 = 3,
        .phaseSeg2 = 2,
        .preDivider = 0,
        .rJumpwidth = 1
    },
    .bitrate_cbt = {
        .propSeg = 7,
        .phaseSeg1 = 3,
        .phaseSeg2 = 2,
        .preDivider = 0,
        .rJumpwidth = 1
    },
    .transfer_type = FLEXCAN_RXFIFO_USING_INTERRUPTS,
    .rxFifoDMAChannel = 0U
};
接口使用
FLEXCAN_DRV_SetBitrate
设置波特率
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_SetBitrate
 * Description   : Set FlexCAN baudrate.
 * This function will set up all the time segment values for classical frames or the
 * extended time segments for the arbitration phase of FD frames. Those time segment
 * values are passed in by the user and are based on the required baudrate.
 *
 * Implements    : FLEXCAN_DRV_SetBitrate_Activity
 *END**************************************************************************/
void FLEXCAN_DRV_SetBitrate(uint8_t instance, const flexcan_time_segment_t *bitrate)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    DEV_ASSERT(bitrate != NULL);
    CAN_Type * base = g_flexcanBase[instance];
#if FEATURE_CAN_HAS_FD
    bool fdEnabled = FLEXCAN_IsFDEnabled(base);
#endif
    FLEXCAN_EnterFreezeMode(base);
#if FEATURE_CAN_HAS_FD
    if (fdEnabled)
    {
        /* Set extended time segments*/
        FLEXCAN_SetExtendedTimeSegments(base, bitrate);
    }
    else
#endif
    {
        /* Set time segments*/
        FLEXCAN_SetTimeSegments(base, bitrate);
    }
    FLEXCAN_ExitFreezeMode(base);
}FLEXCAN_DRV_GetBitrate
获取波特率
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_GetBitrate
 * Description   : Get FlexCAN baudrate.
 * This function will be return the current bit rate settings for classical frames
 * or the arbitration phase of FD frames.
 *
 * Implements    : FLEXCAN_DRV_GetBitrate_Activity
 *END**************************************************************************/
void  FLEXCAN_DRV_GetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    DEV_ASSERT(bitrate != NULL);
    const CAN_Type * base = g_flexcanBase[instance];
    /* Get the time segments*/
    FLEXCAN_GetTimeSegments(base, bitrate);
}FLEXCAN_DRV_SetRxMaskType
设置接收掩码类型
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_SetMasktype
 * Description   : Set RX masking type.
 * This function will set RX masking type as RX global mask or RX individual
 * mask.
 *
 * Implements    : FLEXCAN_DRV_SetRxMaskType_Activity
 *END**************************************************************************/
void  FLEXCAN_DRV_SetRxMaskType(uint8_t instance, flexcan_rx_mask_type_t type)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    CAN_Type * base = g_flexcanBase[instance];
    FLEXCAN_EnterFreezeMode(base);
    FLEXCAN_SetRxMaskType(base, type);
    FLEXCAN_ExitFreezeMode(base);
}FLEXCAN_DRV_SetRxFifoGlobalMask
设置接收队列掩码
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_SetRxFifoGlobalMask
 * Description   : Set Rx FIFO global mask as the 11-bit standard mask or the
 * 29-bit extended mask.
 *
 * Implements    : FLEXCAN_DRV_SetRxFifoGlobalMask_Activity
 *END**************************************************************************/
void FLEXCAN_DRV_SetRxFifoGlobalMask(
    uint8_t instance,
    flexcan_msgbuff_id_type_t id_type,
    uint32_t mask)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    flexcan_rx_fifo_id_element_format_t formatType;
    CAN_Type * base = g_flexcanBase[instance];
    uint32_t calcMask = 0U;
    FLEXCAN_EnterFreezeMode(base);
    if (true == FLEXCAN_IsRxFifoEnabled(base))
    {
		formatType = FLEXCAN_GetRxFifoIdFormat(base);
		calcMask = FLEXCAN_GetRxFifoMask(id_type, formatType, mask);
		switch (formatType)
		{
			case FLEXCAN_RX_FIFO_ID_FORMAT_A :
				FLEXCAN_SetRxFifoGlobalMask(base, calcMask);
				break;
			case FLEXCAN_RX_FIFO_ID_FORMAT_B :
				FLEXCAN_SetRxFifoGlobalMask(base, (calcMask | (calcMask >> FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1)));
				break;
			case FLEXCAN_RX_FIFO_ID_FORMAT_C :
				FLEXCAN_SetRxFifoGlobalMask(base, (calcMask | (calcMask >> FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1) |
												  	  	  	  (calcMask >> FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2) |
															  (calcMask >> FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3)));
				break;
			default :
				/* Will Enable all filter fields mask */
				FLEXCAN_SetRxFifoGlobalMask(base, 0xFFFFFFFFU);
				break;
		}
    }
    FLEXCAN_ExitFreezeMode(base);
}FLEXCAN_DRV_SetRxMbGlobalMask
设置接收报文缓冲区的掩码
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_SetRxMbGlobalMask
 * Description   : Set Rx Message Buffer global mask as the 11-bit standard mask
 * or the 29-bit extended mask.
 *
 * Implements    : FLEXCAN_DRV_SetRxMbGlobalMask_Activity
 *END**************************************************************************/
void FLEXCAN_DRV_SetRxMbGlobalMask(
    uint8_t instance,
    flexcan_msgbuff_id_type_t id_type,
    uint32_t mask)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    CAN_Type * base = g_flexcanBase[instance];
    FLEXCAN_EnterFreezeMode(base);
    if (id_type == FLEXCAN_MSG_ID_STD)
    {
        /* Set standard global mask for RX MB*/
        FLEXCAN_SetRxMsgBuffGlobalStdMask(base, mask);
    }
    else if (id_type == FLEXCAN_MSG_ID_EXT)
    {
        /* Set extended global mask for RX MB*/
        FLEXCAN_SetRxMsgBuffGlobalExtMask(base, mask);
    }
    else {
        /* Should not get here */
    }
    FLEXCAN_ExitFreezeMode(base);
}FLEXCAN_DRV_Init
初始化接口
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_Init
 * Description   : Initialize FlexCAN driver.
 * This function will select a source clock, reset FlexCAN module, set maximum
 * number of message buffers, initialize all message buffers as inactive, enable
 * RX FIFO if needed, mask all mask bits, disable all MB interrupts, enable
 * FlexCAN normal mode, and enable all the error interrupts if needed.
 *
 * Implements    : FLEXCAN_DRV_Init_Activity
 *END**************************************************************************/
status_t FLEXCAN_DRV_Init(
   uint8_t instance,
   flexcan_state_t *state,
   const flexcan_user_config_t *data)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    DEV_ASSERT(state != NULL);
    DEV_ASSERT(g_flexcanStatePtr[instance] == NULL);
#ifdef ERRATA_E10595
    if (instance != 0U)
    {
    	DEV_ASSERT((MC_ME->GS & MC_ME_GS_S_FXOSC_MASK) != 0U);
    }
#endif
    status_t result;
    CAN_Type * base = g_flexcanBase[instance];
    flexcan_time_segment_t bitrate;
    status_t osifStat;
    uint32_t i, j;
    if(FLEXCAN_IsEnabled(base))
    {
        /* To enter Disable Mode requires FreezMode first */
        FLEXCAN_EnterFreezeMode(base);
        FLEXCAN_Disable(base);
    }
#if FEATURE_CAN_HAS_PE_CLKSRC_SELECT
    /* Select a source clock for the FlexCAN engine */
    FLEXCAN_SelectClock(base, data->pe_clock);
#endif
    /* Enable the CAN clock */
    FLEXCAN_Enable(base);
    FLEXCAN_EnterFreezeMode(base);
    /* Initialize FLEXCAN device */
    FLEXCAN_Init(base);
#ifdef ERRATA_E10368
#if FEATURE_CAN_HAS_FD
    FLEXCAN_Errata10368(instance, data);
#endif /* FEATURE_CAN_HAS_FD */
#endif /* ERRATA_E10368 */
#if FEATURE_CAN_HAS_FD
    /* Enable/Disable FD and check FD was set as expected. Setting FD as enabled
     * might fail if the current CAN instance does not support FD. */
    FLEXCAN_SetFDEnabled(base, data->fd_enable);
    if (FLEXCAN_IsFDEnabled(base) != data->fd_enable)
    {
        return STATUS_ERROR;
    }
    /* If the FD feature is enabled, enable the Stuff Bit Count, in order to be
     * ISO-compliant. */
    FLEXCAN_SetStuffBitCount(base, data->fd_enable);
#endif
    /* Disable the self reception feature if FlexCAN is not in loopback mode. */
    if (data->flexcanMode != FLEXCAN_LOOPBACK_MODE)
    {
        FLEXCAN_SetSelfReception(base, false);
    }
    /* Enable RxFIFO feature, if requested. This might fail if the FD mode is
     * enabled. */
    if (data->is_rx_fifo_needed)
    {
        result = FLEXCAN_EnableRxFifo(base, (uint32_t)data->num_id_filters);
        if (result != STATUS_SUCCESS)
        {
            return result;
        }
    }
#if FEATURE_CAN_HAS_DMA_ENABLE
    /* Enable DMA support for RxFIFO transfer, if requested. */
    if (data->transfer_type == FLEXCAN_RXFIFO_USING_DMA)
    {
        if (FLEXCAN_IsRxFifoEnabled(base))
        {
            FLEXCAN_SetRxFifoDMA(base, true);
        }
        else
        {
            return STATUS_ERROR;
        }
    }
    if (data->transfer_type == FLEXCAN_RXFIFO_USING_INTERRUPTS)
    {
    	FLEXCAN_SetRxFifoDMA(base, false);
    }
#endif
#if FEATURE_CAN_HAS_FD
    /* Set payload size. */
    FLEXCAN_SetPayloadSize(base, data->payload);
#endif
    result = FLEXCAN_SetMaxMsgBuffNum(base, data->max_num_mb);
    if (result != STATUS_SUCCESS)
    {
        return result;
    }
#if FEATURE_CAN_HAS_FD
    /* Set bit rate. */
    if (FLEXCAN_IsFDEnabled(base))
    {
        bitrate = data->bitrate;
        FLEXCAN_SetExtendedTimeSegments(base, &bitrate);
        bitrate = data->bitrate_cbt;
        FLEXCAN_SetFDTimeSegments(base, &bitrate);
    }
    else
#endif
    {
        bitrate = data->bitrate;
        FLEXCAN_SetTimeSegments(base, &bitrate);
    }
    /* Select mode */
    FLEXCAN_SetOperationMode(base, data->flexcanMode);
    if (data->flexcanMode != FLEXCAN_FREEZE_MODE)
    {
    	FLEXCAN_ExitFreezeMode(base);
    }
    /* Enable FlexCAN interrupts.*/
    FLEXCAN_EnableIRQs(instance);
    for (i = 0; i < FEATURE_CAN_MAX_MB_NUM; i++)
    {
        osifStat = OSIF_SemaCreate(&state->mbs[i].mbSema, 0U);
        if (osifStat != STATUS_SUCCESS)
        {
            for (j = 0; j < i; j++)
            {
                (void)OSIF_SemaDestroy(&state->mbs[j].mbSema);
            }
            return STATUS_ERROR;
        }
        state->mbs[i].isBlocking = false;
        state->mbs[i].mb_message = NULL;
        state->mbs[i].state = FLEXCAN_MB_IDLE;
    }
#if FEATURE_CAN_HAS_MEM_ERR_DET
    FLEXCAN_DisableMemErrorDetection(base);
#endif
    /* Store transfer type and DMA channel number used in transfer */
    state->transferType = data->transfer_type;
#if FEATURE_CAN_HAS_DMA_ENABLE
    state->rxFifoDMAChannel = data->rxFifoDMAChannel;
#endif
    /* Clear Callbacks in case of autovariables garbage */
    state->callback = NULL;
    state->callbackParam = NULL;
    state->error_callback = NULL;
    state->errorCallbackParam = NULL;
    /* Save runtime structure pointers so irq handler can point to the correct state structure */
    g_flexcanStatePtr[instance] = state;
    return (STATUS_SUCCESS);
}FLEXCAN_DRV_Deinit
逆初始化
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_Deinit
 * Description   : Shutdown a FlexCAN module.
 * This function will disable all FlexCAN interrupts, and disable the FlexCAN.
 *
 * Implements    : FLEXCAN_DRV_Deinit_Activity
 *END**************************************************************************/
status_t FLEXCAN_DRV_Deinit(uint8_t instance)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    CAN_Type * base = g_flexcanBase[instance];
    const flexcan_state_t * state = g_flexcanStatePtr[instance];
    status_t result = STATUS_SUCCESS;
    status_t osifStat;
    uint32_t i;
    /* Disable FlexCAN interrupts.*/
    if (state != NULL)
    {
		if (state->error_callback != NULL)
		{
			FLEXCAN_SetErrIntCmd(base, FLEXCAN_INT_ERR, false);
			FLEXCAN_SetErrIntCmd(base, FLEXCAN_INT_RX_WARNING, false);
			FLEXCAN_SetErrIntCmd(base, FLEXCAN_INT_TX_WARNING, false);
			FLEXCAN_SetErrIntCmd(base, FLEXCAN_INT_BUSOFF, false);
		}
    }
#if FEATURE_CAN_HAS_WAKE_UP_IRQ
    if (g_flexcanWakeUpIrqId[instance] != NotAvail_IRQn)
    {
        INT_SYS_DisableIRQ(g_flexcanWakeUpIrqId[instance]);
    }
#endif
    INT_SYS_DisableIRQ(g_flexcanErrorIrqId[instance]);
    INT_SYS_DisableIRQ(g_flexcanBusOffIrqId[instance]);
    for (i = 0; i < FEATURE_CAN_MB_IRQS_MAX_COUNT; i++)
    {
        if (g_flexcanOredMessageBufferIrqId[i][instance] != NotAvail_IRQn)
        {
            INT_SYS_DisableIRQ(g_flexcanOredMessageBufferIrqId[i][instance]);
        }
    }
    if(FLEXCAN_IsEnabled(g_flexcanBase[instance]))
    {
        /* Enter Freeze Mode Required before to enter Disabled Mode */
        FLEXCAN_EnterFreezeMode(g_flexcanBase[instance]);
        /* Disable FlexCAN.*/
        FLEXCAN_Disable(g_flexcanBase[instance]);
        /* Check if the state have been initialized */
    }
    if (state != NULL)
    {
		for (i = 0; i < FEATURE_CAN_MAX_MB_NUM; i++)
		{
			osifStat = OSIF_SemaDestroy(&state->mbs[i].mbSema);
			if (osifStat != STATUS_SUCCESS)
			{
				result = STATUS_ERROR;
			}
		}
    }
    if (result == STATUS_SUCCESS)
    {
    	/* Clear state pointer that is checked by FLEXCAN_DRV_Init */
    	g_flexcanStatePtr[instance] = NULL;
    }
    return result;
}FLEXCAN_DRV_ConfigTxMb
配置发送报文缓存区,入参为索引、缓存区ID、数据信息结构体、报文ID。
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_ConfigTxMb
 * Description   : Configure a Tx message buffer.
 * 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 set up the message buffer fields,
 * configure the message buffer code for Tx buffer as INACTIVE, and enable the
 * Message Buffer interrupt.
 *
 * Implements    : FLEXCAN_DRV_ConfigTxMb_Activity
 *END**************************************************************************/
status_t FLEXCAN_DRV_ConfigTxMb(
    uint8_t instance,
    uint8_t mb_idx,
    const flexcan_data_info_t *tx_info,
    uint32_t msg_id)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    DEV_ASSERT(tx_info != NULL);
    flexcan_msgbuff_code_status_t cs;
    CAN_Type * base = g_flexcanBase[instance];
    /* Initialize transmit mb*/
    cs.dataLen = tx_info->data_length;
    cs.msgIdType = tx_info->msg_id_type;
#if FEATURE_CAN_HAS_FD
    cs.enable_brs = tx_info->enable_brs;
    cs.fd_enable = tx_info->fd_enable;
    cs.fd_padding = tx_info->fd_padding;
#endif
    cs.code = (uint32_t)FLEXCAN_TX_INACTIVE;
    return FLEXCAN_SetTxMsgBuff(base, mb_idx, &cs, msg_id, NULL);
}FLEXCAN_DRV_SendBlocking
阻塞发送
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_SendBlocking
 * Description   : This function sends a CAN frame using a configured message
 * buffer. The function blocks until either the frame was sent, or the specified
 * timeout expired.
 *
 * Implements    : FLEXCAN_DRV_SendBlocking_Activity
 *END**************************************************************************/
status_t FLEXCAN_DRV_SendBlocking(
    uint8_t instance,
    uint8_t mb_idx,
    const flexcan_data_info_t *tx_info,
    uint32_t msg_id,
    const uint8_t *mb_data,
    uint32_t timeout_ms)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    DEV_ASSERT(tx_info != NULL);
    status_t result;
    flexcan_state_t * state = g_flexcanStatePtr[instance];
    CAN_Type * base  = g_flexcanBase[instance];
    result = FLEXCAN_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data, true);
    if (result == STATUS_SUCCESS)
    {
        status_t status;
        /* Enable message buffer interrupt*/
        (void)FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, true);
        status = OSIF_SemaWait(&state->mbs[mb_idx].mbSema, timeout_ms);
        if (status == STATUS_TIMEOUT)
        {
        	if (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE)
        	{
        	    /* Disable message buffer interrupt */
                (void)FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, false);
                /* Clear message buffer flag */
                FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
				FLEXCAN_AbortTxMsgBuff(base, mb_idx);
				uint32_t flexcan_mb_config;
#ifndef ERRATA_E9527
				/* Wait to finish abort operation */
				while(FLEXCAN_GetBuffStatusFlag(base, mb_idx) == 0U)
				{
					/* Do Nothing wait for the flag */
				}
#endif
				volatile const uint32_t *flexcan_mb = FLEXCAN_GetMsgBuffRegion(base, mb_idx);
				flexcan_mb_config = * flexcan_mb;
				/* Check if the MBs have been safely Inactivated */
				if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32_t)FLEXCAN_TX_INACTIVE)
				{
#ifndef ERRATA_E9527
					/* Transmission have occurred */
					result = STATUS_SUCCESS;
#else
	     			/* Transmission have not occurred because it uses the inactivation operation */
					if (FLEXCAN_GetBuffStatusFlag(base, mb_idx) == 0U)
					{
						result = STATUS_TIMEOUT;
					}
					else
					{
						result = STATUS_SUCCESS;
					}
#endif
				}
				if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32_t)FLEXCAN_TX_ABORT)
				{
					/* Transmission have occurred */
						result = STATUS_TIMEOUT;
				}
				/* Clear message buffer flag */
				FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
				state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
			}
        }
    }
    return result;
}FLEXCAN_DRV_Send
普通发送,入参就是索引、报文缓存区ID、发送信息、报文ID、缓存区数据。
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_Send
 * Description   : This function sends a CAN frame using a configured message
 * buffer. The function returns immediately. If a callback is installed, it will
 * be invoked after the frame was sent.
 *
 * Implements    : FLEXCAN_DRV_Send_Activity
 *END**************************************************************************/
status_t FLEXCAN_DRV_Send(
    uint8_t instance,
    uint8_t mb_idx,
    const flexcan_data_info_t *tx_info,
    uint32_t msg_id,
    const uint8_t *mb_data)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    DEV_ASSERT(tx_info != NULL);
    status_t result;
    CAN_Type * base = g_flexcanBase[instance];
    result = FLEXCAN_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data, false);
    if(result == STATUS_SUCCESS)
    {
        /* Enable message buffer interrupt*/
        result = FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, true);
    }
    return result;
}FLEXCAN_DRV_ReceiveBlocking
阻塞接收
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_ReceiveBlocking
 * Description   : This function receives a CAN frame into a configured message
 * buffer. The function blocks until either a frame was received, or the
 * specified timeout expired.
 *
 * Implements    : FLEXCAN_DRV_ReceiveBlocking_Activity
 *END**************************************************************************/
status_t FLEXCAN_DRV_ReceiveBlocking(
    uint8_t instance,
    uint8_t mb_idx,
    flexcan_msgbuff_t *data,
    uint32_t timeout_ms)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    status_t result;
    flexcan_state_t * state = g_flexcanStatePtr[instance];
    CAN_Type * base = g_flexcanBase[instance];
    result = FLEXCAN_StartRxMessageBufferData(instance, mb_idx, data, true);
    if(result == STATUS_SUCCESS)
    {
        status_t status;
        status = OSIF_SemaWait(&state->mbs[mb_idx].mbSema, timeout_ms);
        if (status == STATUS_TIMEOUT)
        {
            /* If the flag is set Successful reception else report TimeOut */
			if(FLEXCAN_GetMsgBuffIntStatusFlag(base,mb_idx) == (uint8_t)0U)
			{
				result = STATUS_TIMEOUT;
			}
			/* Disable message buffer interrupt */
			(void)FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, false);
        }
        /* Consider the MB state has been changed by interrupt as frame received */ 
        if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
        {
        	return STATUS_SUCCESS;
        }
        state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
    }
    return result;
}FLEXCAN_DRV_Receive
普通接收
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_Receive
 * Description   : This function receives a CAN frame into a configured message
 * buffer. The function returns immediately. If a callback is installed, it will
 * be invoked after the frame was received and read into the specified buffer.
 *
 * Implements    : FLEXCAN_DRV_Receive_Activity
 *END**************************************************************************/
status_t FLEXCAN_DRV_Receive(
    uint8_t instance,
    uint8_t mb_idx,
    flexcan_msgbuff_t *data)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    status_t result;
    result = FLEXCAN_StartRxMessageBufferData(instance, mb_idx, data, false);
    return result;
}FLEXCAN_DRV_RxFifoBlocking
阻塞接收到FIFO里面
/*FUNCTION**********************************************************************
 *
 * Function Name : FLEXCAN_DRV_RxFifoBlocking
 * Description   : This function receives a CAN frame using the Rx FIFO. The
 * function blocks until either a frame was received, or the specified timeout
 * expired.
 *
 * Implements    : FLEXCAN_DRV_RxFifoBlocking_Activity
 *END**************************************************************************/
status_t FLEXCAN_DRV_RxFifoBlocking(
    uint8_t instance,
    flexcan_msgbuff_t *data,
    uint32_t timeout_ms)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
    status_t result;
    flexcan_state_t * state = g_flexcanStatePtr[instance];
    CAN_Type * base = g_flexcanBase[instance];
    result = FLEXCAN_StartRxMessageFifoData(instance, data, true);
    if (result == STATUS_SUCCESS)
    {
        result = OSIF_SemaWait(&state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mbSema, timeout_ms);
        if (result == STATUS_TIMEOUT)
        {
        	 /* If the status is updated reception successful else report TimeOut */
			if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_IDLE)
			{
				result = STATUS_SUCCESS;
			}
            /* Disable RX FIFO interrupts*/
            (void)FLEXCAN_SetMsgBuffIntCmd(base, FEATURE_CAN_RXFIFO_FRAME_AVAILABLE, false);
            (void)FLEXCAN_SetMsgBuffIntCmd(base, FEATURE_CAN_RXFIFO_WARNING, false);
            (void)FLEXCAN_SetMsgBuffIntCmd(base, FEATURE_CAN_RXFIFO_OVERFLOW, false);
            
#if FEATURE_CAN_HAS_DMA_ENABLE
            /* Check if transfer is done over DMA and stop transfer */
            if ((state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_RX_BUSY) && (state->transferType == FLEXCAN_RXFIFO_USING_DMA))
            {
                /* This function always return status success */
                (void)EDMA_DRV_StopChannel(state->rxFifoDMAChannel);
            }
#endif
        }
        state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
    }
    return result;
}



















