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的数据拷贝的缓冲区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/168673.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自定义歌曲试听SeekBar

看到这个效果&#xff0c;可能会想到完全自定义一个控件&#xff0c;其实我们在系统Seekbar的基础上&#xff0c;将progressDrawable中progress背景设为透明后&#xff0c;叠加绘制试听状态下的进度区域即可 class PlayerSeekBar JvmOverloads constructor(context: Context,a…

客服中心的客户关系管理核心功能

根据国外的调查&#xff0c;拥有客服中心的运营机构&#xff0c;可以保持85%左右的客户忠诚度&#xff0c;而接受过专业培训的客户中心可以将客户忠诚度提高到99%。客服中心作为客户关系管理的前沿&#xff0c;通过提供服务、实时沟通、搜集与分析客户信息、预测客户需求来提升…

SQL常见函数整理 —— lead()向下偏移

1. 用法 是在窗口函数中使用的函数&#xff0c;它用于获取当前行的下一行&#xff08;后一行&#xff09;的某个列的值。具体来说&#xff0c;LEAD() 函数可用于查找任何给定行的下一行&#xff08;后一行&#xff09;的值&#xff0c;同时也可控制行数偏移量&#xff08;offse…

每日汇评:澳元多头着眼于50%的斐波那契水平

澳元兑美元跳涨至三个月高点上方&#xff0c;并从多种因素中获得支撑&#xff1b; 对美联储已经结束加息的预期继续严重打压美元&#xff1b; 对中国出台更多刺激措施的乐观情绪和积极的风险基调也有利于澳元&#xff1b; 澳元兑美元周一连续获得强劲的后续积极牵引力&#xff…

在列表控件上显示提示信息

当我们在实现列表控件上的提示信息的时候&#xff0c;我们需要处理的一个难点是处理列表条目的折叠和展开这两种情况。 所谓列表条目的折叠&#xff0c;即在大图标模式(Large Icon Mode)下&#xff0c;列表条目的文字过长而被截断的情况。当用户选择这个条目后&#xff0c;条目…

损失函数总结(十五):MSLELoss、RMSLELoss

损失函数总结&#xff08;十五&#xff09;&#xff1a;MSLELoss、RMSLELoss 1 引言2 损失函数2.1 MSLELoss2.2 RMSLELoss 3 总结 1 引言 在前面的文章中已经介绍了介绍了一系列损失函数 (L1Loss、MSELoss、BCELoss、CrossEntropyLoss、NLLLoss、CTCLoss、PoissonNLLLoss、Gau…

城市生命线丨市政综合管廊监测系统的效果

市政综合管廊&#xff0c;又被称为城市生命线&#xff0c;是我们在地下建造的一个智慧而高效的空间。它把市政、电力、通讯、燃气、给排水等各种管线集于一体&#xff0c;解决了城市中反复开挖路面、架空线网密集、管线事故频发等问题&#xff0c;为城市运行提供了重要的基础设…

C#,怎么修改(VS)Visual Studio 2022支持的C#版本

一些文字来自于 Microsoft . &#xff08;只需要读下面的红色文字即可&#xff01;&#xff09; 1 C# 语言版本控制 最新的 C# 编译器根据项目的一个或多个目标框架确定默认语言版本。 Visual Studio 不提供用于更改值的 UI&#xff0c;但可以通过编辑 .csproj 文件来更改值。…

浅谈餐饮业油烟污染现状及在线监测系统的设计与应用

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;城市餐饮业油烟污染成了困扰城区环境保护部门和人民群众日常生活的主要问题。油烟污染已经成为我国一个重大的污染源&#xff0c;是形成PM2.5的重要污染源之一&#xff0c;为了解决餐饮业油烟管理方面存在的问…

linux镜像的下载,系统下载(个人使用)

文章目录 一、系统之家二、国内镜像源三、Centos官网四、安装成功截图五、镜像类型的区别参考文档 一、系统之家 系统之家官网 二、国内镜像源 下载镜像地址&#xff1a; 1、官网地址&#xff1a;https://www.centos.org/ 2、阿里镜像站&#xff1a;https://mirrors.aliyu…

人工智能基础_机器学习041_Sigmoid函数详解_Sigmoid损失函数推导_最大似然函数推导---人工智能工作笔记0081

然后我们再来看一下sigmoid函数的推导过程,可以看到首先我们把 sigmoid的函数写成两种情况 可以看到P(y|x;theta) = htheta(x), y=1 这个时候y=1 也就是是一种分类,然后另一种,就是相减, 是1-htheta(x) 可以看到,把两个公式河道一起就得到了下面的概率公式. 这里是有关概率…

被OpenAI开除后,创始人奥特曼在微软找到了新工作

微软首席执行官纳德拉宣布&#xff0c;OpenAI创始人Sam Altman和Brockman及其同事将加入微软。随后&#xff0c;Altman转发了他的推特。 此前&#xff0c;外媒消息称&#xff0c;OpenAI首席科学家伊尔亚苏茨克维&#xff08;Ilya Sutskever&#xff09;周日晚告知公司员工&…

Dubbo快速实践

文章目录 架构相关概念集群和分布式架构演进 Dubbo概述Dubbo快速入门前置准备配置服务接口配置Provider配置Consumer Dubbo基本使用总结 本文参考https://www.bilibili.com/video/BV1VE411q7dX 架构相关概念 集群和分布式 集群&#xff1a;很多“人”一起 &#xff0c;干一样…

有哪些相见恨晚的stm32学习的方法?

有哪些相见恨晚的stm32学习的方法&#xff1f; 单片机用处这么广&#xff0c;尤其是STM32生态这么火&#xff01;如何快速上手学习呢&#xff1f; 你要考虑的是&#xff0c;要用STM32实现什么&#xff1f;为什么使用STM32而不是用8051&#xff1f;是因为51的频率太低&#xff…

requests库出现AttributeError问题的修复与替代方法

在使用App Engine时&#xff0c;开发者们通常会面临需要发送爬虫ip请求的情况&#xff0c;而Python中的requests库是一个常用的工具&#xff0c;用于处理爬虫ip请求。然而&#xff0c;在某些情况下&#xff0c;开发者可能会遇到一个名为AttributeError的问题&#xff0c;特别是…

软件数字签名是什么?软件数字签名有什么作用?

在当今互联网时代&#xff0c;网络安全威胁日益增加&#xff0c;恶意软件层出不穷&#xff0c;为了防止下载到恶意软件&#xff0c;用户在下载软件时都会确认其是安全可信的。由此&#xff0c;企业需要证明其发布的软件真实可信且未被篡改&#xff0c;如何证明这一点呢&#xf…

MATLAB常用绘图函数的使用

文章目录 绘制一图一线绘制一图多线用法一&#xff1a;plot用法二&#xff1a;hold on 绘制一图多图其他形式的坐标图分段函数绘制方法一&#xff1a;分段写函数的定义域值域方法二&#xff1a;判断定义域方法三&#xff1a;if else 判断 横纵坐标范围设置标题、轴标签、图例、…

JVM基础- 垃圾回收器

基本介绍 Java虚拟机&#xff08;JVM&#xff09;中的垃圾回收器是用来自动管理内存的关键组件。它负责识别并回收不再使用的内存&#xff0c;从而防止内存泄漏。不同的JVM实现提供了多种垃圾回收器&#xff0c;每种回收器都有其特定的使用场景和性能特点。以下是一些常见的JV…

16路模拟信号转RS-485/232,Modbus RTU 通讯协议数据采集24位A/D转换模块 YL29

特点&#xff1a; ● 16路模拟信号采集&#xff0c;隔离转换 RS-485/232输出 ● 采用24位AD转换器&#xff0c;测量精度优于0.05% ● 通过RS-485/232接口可以程控校准模块精度 ● 信号输入 / 输出之间隔离耐压3000VDC ● 宽电源供电范围&#xff1a;8 ~ 32VDC ● 可靠性高…
最新文章