AutoSAR CANIF层配置代码分析

2023-11-20 19:20

本文主要是介绍AutoSAR CANIF层配置代码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

CAN物理控制单元

   配置:

生成的代码:

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。

    示意图:

发送状态:

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控制器的通道

配置:

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

  • IsDataChecksumTxPdu :数据校验

配置:

代码位置:

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

上位机配置:

代码位置:

  • UpperLayerTxPduId: PDU 的ID

示例:

    

代码:

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

发送确认回调函数

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

上位机配置:

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是上位机配置的:

   

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 CANIF层配置代码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/396840

相关文章

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

IDEA自动生成注释模板的配置教程

《IDEA自动生成注释模板的配置教程》本文介绍了如何在IntelliJIDEA中配置类和方法的注释模板,包括自动生成项目名称、包名、日期和时间等内容,以及如何定制参数和返回值的注释格式,需要的朋友可以... 目录项目场景配置方法类注释模板定义类开头的注释步骤类注释效果方法注释模板定义方法开头的注释步骤方法注

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

售价599元起! 华为路由器X1/Pro发布 配置与区别一览

《售价599元起!华为路由器X1/Pro发布配置与区别一览》华为路由器X1/Pro发布,有朋友留言问华为路由X1和X1Pro怎么选择,关于这个问题,本期图文将对这二款路由器做了期参数对比,大家看... 华为路由 X1 系列已经正式发布并开启预售,将在 4 月 25 日 10:08 正式开售,两款产品分别为华

SQL server配置管理器找不到如何打开它

《SQLserver配置管理器找不到如何打开它》最近遇到了SQLserver配置管理器打不开的问题,尝试在开始菜单栏搜SQLServerManager无果,于是将自己找到的方法总结分享给大家,对SQ... 目录方法一:桌面图标进入方法二:运行窗口进入方法三:查找文件路径方法四:检查 SQL Server 安

Python Transformer 库安装配置及使用方法

《PythonTransformer库安装配置及使用方法》HuggingFaceTransformers是自然语言处理(NLP)领域最流行的开源库之一,支持基于Transformer架构的预训练模... 目录python 中的 Transformer 库及使用方法一、库的概述二、安装与配置三、基础使用:Pi

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求