AutoSAR CANIF层配置代码分析

CAN物理控制单元

   配置:AutoSAR CANIF层配置代码分析_第1张图片

生成的代码:

AutoSAR CANIF层配置代码分析_第2张图片

CanIf_CtrlStates 解析

   类型:

typedef union CanIf_CtrlStatesUTag
{
	CanIf_CtrlStatesType raw[3];
	CanIf_CtrlStatesStructSType str;
}CanIf_CtrlStatesUType;

typedef struct sCanIf_CtrlStatesType
{
	CanIf_ControllerModeType CtrlMode;
	CanIf_PduGetModeType PduMode;
	CanIf_NotifStatusType TxConfState;
}CanIf_CtrlStatesType;

typedef struct CanIf_CtrlStatesStructSTag
{
	CanIf_CtrlStatesType ADSCAN;
	CanIf_CtrlStatesType BCAN;
	CanIf_CtrlStatesType PCAN;
}CanIf_CtrlStatesStructSType;

CAN控制器模式:

typedef enum 
{
    CANIF_CS_UNINIT = 0u,
    CANIF_CS_STOPPED,
    CANIF_CS_STARTED,
    CANIF_CS_SLEEP
} CanIf_ControllerModeType;

PDU模式:

     只允许在对应的控制器模式等于CAN_CS_STARTED时,更改PDU通道模式,在初始化期间,CanIf应该将每个通道切换到CANIF_OFFLINE。如果调用CanIf_SetControllerMode(),则CanIf会将对应通道的PDU通道模式设置为CANIF_OFFLINE。

     如果调用CanIf_SetControllerMode()或CanIf_ControllerBusOff(),则CanIf应将相应通道的PDU通道模式设置为CANIF_TX_OFFLINE。

    示意图:

AutoSAR CANIF层配置代码分析_第3张图片

发送状态:

typedef enum
{
    CANIF_NO_NOTIFICATION = 0u,
    CANIF_TX_RX_NOTIFICATION
} CanIf_NotifStatusType;

CanIf_TxPduConfig

typedef struct sCanIf_TxPduConfigType
{
	CanIf_UpperLayerTxPduIdOfTxPduConfigType UpperLayerTxPduId;
	uint16 CanId;
	boolean IsDataChecksumTxPdu;
	boolean IsTxPduTruncation;
	CanIf_ControllerType CtrlStatesIdx;
	uint8 MailBoxConfigIdx;
	CanIf_TxConfFctListIdxType TxConfirmationFctListIdx;
	uint8 TxPduLength;
}CanIf_TxPduConfigType;
  • CtrlStatesIdx: CAN控制器的通道

配置:

AutoSAR CANIF层配置代码分析_第4张图片

  • CanId: canid 有四种配置 扩展CAN 、标准CAN、扩展CANFD、标准CANFD。

AutoSAR CANIF层配置代码分析_第5张图片

  • IsDataChecksumTxPdu :数据校验

配置:

AutoSAR CANIF层配置代码分析_第6张图片

代码位置:

AutoSAR CANIF层配置代码分析_第7张图片

  • IsTxPduTruncation: 为TRUE时,配置最大长度。

上位机配置:

AutoSAR CANIF层配置代码分析_第8张图片

代码位置:

AutoSAR CANIF层配置代码分析_第9张图片

AutoSAR CANIF层配置代码分析_第10张图片

  • UpperLayerTxPduId: PDU 的ID

示例:

    AutoSAR CANIF层配置代码分析_第11张图片

代码:

AutoSAR CANIF层配置代码分析_第12张图片

  • MailBoxConfigIdx :CANIF 信箱,后面介绍
  • TxConfirmationFctListIdx:CanIf_TxConfirmationFctList[]数组下标

发送确认回调函数

CONST(CanIf_TxConfirmationFctType, CANIF_VAR_NOINIT) CanIf_TxConfirmationFctList[2] = {
	CAN_NM_CanIfTxConfirmation,
	PDUR_CanIfTxConfirmation,
};
  • TxPduLength: 发送PDU长度

上位机配置:

AutoSAR CANIF层配置代码分析_第13张图片

CanIf_MailBoxConfig

   mailbox 涉及的数据结构挺多的,主要是CAN控制器发送的缓存buffer fifo之类的

CanIf_CanIfCtrlId2MappedTxBuffersConfig

 /* Get all HTHs with configured Tx-buffer of affected CAN-channel */
    for(idx2MappedTxBufferCfg = CanIf_CanIfCtrlId2MappedTxBuffersConfig[ControllerId].StartIdx;
        idx2MappedTxBufferCfg < CanIf_CanIfCtrlId2MappedTxBuffersConfig[ControllerId].EndIdx;
        idx2MappedTxBufferCfg++ )

从上面的代码可以得出,主要是为每个CAN控制器所配置的TX buffer

CONST(CanIf_CanIfCtrlId2MappedTxBuffersConfigType, CANIF_VAR_NOINIT) CanIf_CanIfCtrlId2MappedTxBuffersConfig[1] = {
	{ 3u, 0u },
};
typedef struct sCanIf_CanIfCtrlId2MappedTxBuffersConfigType
{
	uint8 EndIdx;
	uint8 StartIdx;
}CanIf_CanIfCtrlId2MappedTxBuffersConfigType;

CanIf_MappedTxBuffersConfig

hth = CanIf_MappedTxBuffersConfig[idx2MappedTxBufferCfg].MailBoxConfigIdx;


typedef struct sCanIf_MappedTxBuffersConfigType
{
	uint8 MailBoxConfigIdx;
}CanIf_MappedTxBuffersConfigType;
CONST(CanIf_MappedTxBuffersConfigType, CANIF_VAR_NOINIT) CanIf_MappedTxBuffersConfig[3] = {
	{ 1u },
	{ 2u },
	{ 5u },
};

主要是此变量主要是去映射到CanIf_MailBoxConfig的配置。

CanIf_MailBoxConfig

定义:

 

typedef struct sCanIf_MailBoxConfigType
{
	uint8 CtrlStatesIdx;
	uint8 PduIdFirst;
	uint8 PduIdLast;
	uint8 TxBufferCfgIdx;
	uint8 TxBufferHandlingType;
	CanIf_MailBoxTypeType MailBoxType;
}CanIf_MailBoxConfigType;

CONST(CanIf_MailBoxConfigType, CANIF_VAR_NOINIT) CanIf_MailBoxConfig[6] = {
	{ 0u, 0u, 1u, 255u,  CANIF_TXBUFFER_HANDLINGTYPE_NONE, CANIF_UnusedCANMailbox },
	{ 0u, 0u, 0u, 0u,  CANIF_TXBUFFER_HANDLINGTYPE_FIFO, CANIF_TxBasicCANMailbox },
	{ 1u, 0u, 0u, 2u,  CANIF_TXBUFFER_HANDLINGTYPE_FIFO, CANIF_TxBasicCANMailbox },
	{ 1u, 2u, 47u, 255u,  CANIF_TXBUFFER_HANDLINGTYPE_NONE, CANIF_UnusedCANMailbox },
	{ 2u, 49u, 50u, 255u,  CANIF_TXBUFFER_HANDLINGTYPE_NONE, CANIF_UnusedCANMailbox },
	{ 2u, 0u, 0u, 1u,  CANIF_TXBUFFER_HANDLINGTYPE_FIFO, CANIF_TxBasicCANMailbox },
};

这里面有个TxBufferCfgIdx,是CanIf_TxBufferFifoConfig的下标。

CanIf_TxBufferFifoConfig

  主要是TXBuffer位置的配置

typedef struct sCanIf_TxBufferFifoConfigType
{
	uint16 TxFifoQueueDataEndIdx;
	uint16 TxFifoQueueDataStartIdx;
	uint8 SizeOfOnePayloadEl;
	uint8 TxBufferFifoBaseIdx;
	uint16 TxFifoQueueBaseEndIdx;
	uint8 TxFifoQueueBaseLength;
	uint16 TxFifoQueueBaseStartIdx;
}CanIf_TxBufferFifoConfigType;

CONST(CanIf_TxBufferFifoConfigType, CANIF_VAR_NOINIT) CanIf_TxBufferFifoConfig[3] = {
	{ 800u, 0u, 8u, 0u, 100u, 100u, 0u },
	{ 1600u, 800u, 8u, 1u, 200u, 100u, 100u },
	{ 2400u, 1600u, 8u, 2u, 300u, 100u, 200u },
};

    其中的8为单位递增单元,0、800、1600、为3个buff开始的位置,3个100 对应的是 800 除以8,TxFifoQueueBaseEndIdx的结构没有用到,与之对应的结构是CanIf_TxFifoQueueData。

    其中TxBufferFifoBaseIdx为 CanIf_TxBufferFifoBase.raw数组的下标。其中TxFifoQueueBaseLength 为100是上位机配置的:

   AutoSAR CANIF层配置代码分析_第14张图片

CanIf_TxBufferFifoBase

typedef union CanIf_TxBufferFifoBaseUTag
{
	CanIf_TxBufferFifoBaseType raw[3];
	CanIf_TxBufferFifoBaseStructSType str;
}CanIf_TxBufferFifoBaseUType;

   在CanIf_ClearQueue函数中进行初始化的

switch (CanIf_MailBoxConfig[hth].TxBufferHandlingType)
        {
            case CANIF_TXBUFFER_HANDLINGTYPE_FIFO:
                /* Clearing of FIFO */
                txBufferFifoBaseIdx = CanIf_TxBufferFifoConfig[txBufferCfgIdx].TxBufferFifoBaseIdx;
                /* Set ReadIdx, WriteIdx and QueueCounter to 0 */
                CanIf_TxBufferFifoBase.raw[txBufferFifoBaseIdx].eWriteIdx = 0;
                CanIf_TxBufferFifoBase.raw[txBufferFifoBaseIdx].eReadIdx = 0;
                CanIf_TxBufferFifoBase.raw[txBufferFifoBaseIdx].eQueueCounter = 0;
                break;

            default:
                break;
        }

CanIf_TxFifoQueueData 

typedef union CanIf_TxFifoQueueDataUTag
{
	uint8 raw[2400];
	CanIf_TxFifoQueueDataStructSType str;
}CanIf_TxFifoQueueDataUType;

CanIf_TransmitSubWrite API 介绍

 定义:

CANIF_LOCAL_INLINE FUNC(Std_ReturnType, CANIF_CODE) CanIf_TransmitSubWrite(P2CONST(Can_PduType, AUTOMATIC, AUTOMATIC) localPduPtr)

此函数传递的参数为PDU,数据结构为:

typedef struct Can_PduTypeTag
{
	Can_IdType id;
	uint8 length;
	Can_SduPtrType sdu;
	PduIdType swPduHandle;
} Can_PduType;

    此函数主要判断CAN控制器的模式是否使能,PDU是否使能,以及PDU的校验,之后调用CanIf_TransmitSubWrite 函数。

CanIf_TransmitSubWrite

      在此函数中判断此PDU的发送方式是否为FIFO,如果为FIFO则判断FIFO是否为空,为空则直接调用Can_Write().

相关代码:

if(CanIf_MailBoxConfig[CanIf_TxPduConfig[localPduPtr->swPduHandle].MailBoxConfigIdx].TxBufferHandlingType == CANIF_TXBUFFER_HANDLINGTYPE_FIFO)
	{
		/* If Tx-PDU is mapped to Tx-buffer of handling type FIFO it must only be transmitted directly if FIFO is empty */
		doCanWrite = CanIf_TransmitSubCheckFiFoQueueEmpty(localPduPtr->swPduHandle);
	}

	if(doCanWrite == TRUE)
	{
		//txResult = Can_Write((CanIf_HwHandleType)CanIf_TxPduConfig[localPduPtr->swPduHandle].MailBoxConfigIdx, (P2CONST(Can_PduType, AUTOMATIC, CANIF_VAR_STACK))localPduPtr);
	}

否则调用CanIf_TransmitSubHandleTxResBusy,缓存到队列 buffer中。

CanIf_TransmitSubHandleTxResBusy

   此函数主要是将PDU的数据拷贝到缓冲区,也就是TX buffer中。

/* Evaluate FIFO-WriteIdx */
						txFifoQueueBaseStartIdx = CanIf_TxBufferFifoConfig[txBufferCfgIdx].TxFifoQueueBaseStartIdx;
						writeIdx = CanIf_TxBufferFifoBase.raw[txBufferFifoBaseIdx].eWriteIdx;
						/* Store length of Tx-PDU at FIFO-WriteIdx */
						CanIf_TxFifoQueueBase.raw[writeIdx + txFifoQueueBaseStartIdx].eBaseParams.eSduLength = localPduPtr->length;
						/* Store the PDU ID of the Tx-PDU at FIFO-WriteIdx */
						CanIf_TxFifoQueueBase.raw[writeIdx + txFifoQueueBaseStartIdx].eTxPduId = localPduPtr->swPduHandle;

其中txFifoQueueBaseStartIdx为0,100,200 乘以8 就是每个buff开始写的位置。0,800,1600.

后面的是用CanIf_TxFifoQueueBase保存PDU的长度和PDU 的ID。

queueDataStartIdx = ((uint32_least)writeIdx * (uint32_least)CanIf_TxBufferFifoConfig[txBufferCfgIdx].SizeOfOnePayloadEl) + CanIf_TxBufferFifoConfig[txBufferCfgIdx].TxFifoQueueDataStartIdx;
						/* Store data of Tx-PDU at FIFO-WriteIdx */
						memcpy(&CanIf_TxFifoQueueData.raw[queueDataStartIdx], localPduPtr->sdu, localPduPtr->length);
						/* Increment the FIFO-counter */
						CanIf_TxBufferFifoBase.raw[txBufferFifoBaseIdx].eQueueCounter++;

将PDU的数据拷贝的缓冲区。

你可能感兴趣的:(AutoSAR,单片机,autosar)