当前位置: 首页 > news >正文

手写Autosar架构的CAN通讯协议栈2(CanIf模块详解-上)

目录

前言

参考资料介绍

Autosar架构Can通讯链路介绍

Can报文接收链路的理解与实现

功能实现1:软件过滤

功能实现2:接收报文查找算法(软件滤波类型)

功能实现3:Can邮箱索引在接收报文中的使用

功能实现4:接收报文为一段范围的CanId

源码展示

结语


前言

一直以来,我们都是以Autosar工具链使用者的角度去理解Autosar各个模块以及配置项,很多模块、配置项总感觉理解不够深入。

通过看Autosar标准规范去理解吧,规范又过于抽象

(Autosar标准规范举例)

看工具链的代码吧,代码量实在是太大,不知从何看起,实在是没办法从头到尾研究完某个模块的代码。

(HaloOS代码举例)

但仔细想了想,不理解或许是正常的。

因为人家Autosar工具链厂家设计的代码,是把Autosar标准的所有功能都实现了。

他们的目的,是把这套工具链卖给整个行业内的各个企业、匹配各种需求场景。

......

然而,如果我们以设计者的角度去理解Autosar模块,情况就完全不一样了。

这篇文章,我们就以设计者的角度,去从0去实现CanIf模块,从根源上理解Autosar CanIf模块功能、各个配置项的意义。

参考资料介绍

在我们进入正题之前,先把我们会用到的资料列一下:

1、Autosar标准规范-MCAL-Can模块规范

AUTOSAR_SWS_CANDriver.pdf

2、Autosar标准规范-Bsw-CanIf模块规范

AUTOSAR_SWS_CANInterface.pdf

3、HaloOs开源代码(Can模块代码、CanIf模块代码)

https://gitee.com/haloos/

Autosar架构Can通讯链路介绍

在深入了解CanIf模块之前,我们先从宏观视角了解一下CanIf模块在Autosar架构Can协议栈中的位置:

(图片来源:AUTOSAR_SWS_CANInterface.pdf)

可以看到,CanIf的上层模块非常多,比如CanTp(诊断报文)、PduR(应用报文)、CanNm(网管)等等。

下层模块我们主要关心2个:Can模块(Can控制器)、Can收发器模块。

好了,CanIf模块所处的位置及上下层模块有个概念就行,我们暂时不去纠结各个模块的作用。

接下来,我们就从微观角度,理解CanIf模块功能。

Can报文接收链路的理解与实现

功能实现1:软件过滤

我们在了解CanIf模块软件过滤的功能前,先来看看Can模块收到报文后,是怎么传给CanIf模块的:

当接收到CAN总线的Can报文时,Can模块会把CANID、报文类型、DLC这些内容一起传给CanIf模块,如下图所示:

其中Can报文类型已经包含在CanIf_RxIndication的CanId参数里面了。

举个栗子:

0x00000123则代表标准帧、CAN格式的0x123报文

0x01000123则代表标准帧、CANFD格式的0x123报文。

好了,了解了这些内容后,我们就可以来认识一下CanIf模块的软件过滤功能了。

我们从前面的Autosar架构图我们看到:“所有的Can报文都必须经过CanIf模块”:

这句话实际上隐藏了很多信息:

为什么接收报文经过了CanIf模块,就知道要往哪个上层送?

如果是Can矩阵(或DBC)里面没有定义的报文,CanIf能知道上层模块是谁吗?

因此,对于接收报文来说,很重要的一个功能就出来了:软件过滤。

CanIf模块会定义Can矩阵(或DBC)里所有需要接收的报文的CANID报文类型DLC

具体怎么定义呢?

我们来看下CanIf模块的代码:

可以看到,上图中结构体数组大小为2,即定义了2条接收报文。(这个结构体数组我们下面会经常用到,hrh_rx_pdu_canif_hrh_cfg[ ]

数组中详细定义了2条接收报文对应的报文属性(CanID、DLC、报文类型)。

报文从Can模块送至CanIf模块后,CanIf模块会轮询上面这个数组,并把Can模块传过来的CanId跟数组中的每个报文的CanId进行对比。

情况1:如果在数组中找到了对应的CanId,那么就认为成功接收到了我们需要的报文,然后再根据用户需求决定是否进行报文DLC判断,如果需要判断DLC,且最后DLC检查通过了,则把报文送到对应的上层模块进行处理。

情况2:如果找完了一整个数组都没找到对应的CanId(实际上不是找完一整个数组,原因我们下面会讲到,我们这里暂时认为找完了一整个数组),或需要检查DLC,但DLC检查不通过,CanIf模块就会把这条报文丢掉,不再继续送到上层进行处理。

至于每条报文的上层模块是哪里,则取决于数组里面的这个参数:

朋友们,我们上面说的这么多内容,不就是对应Autosar工具链接收报文的这些配置项嘛:

功能实现2:接收报文查找算法(软件滤波类型

好了,我们现在知道接收报文要进行软件过滤,从代码层面来说,就是要轮询CanIf模块的接收报文结构体数组hrh_rx_pdu_canif_hrh_cfg[ ],如下图所示(只有2条接收报文):

如果某个项目有几十条,上百条报文呢?

那么,如果还是一个简单的For循环从上到下轮询这个结构体数组,这样的查找方法就会导致浪费很多时间。

因此, CanIf模块中的“SoftwareFilterType” (软件滤波类型)功能就出来了。

于是,静态代码中把“线性查找”、“二分法查找 ”等其它查找方式都实现了,然后用户开发时再根据项目报文数量,开启对应的滤波算法。

这就是软件滤波类型的由来了。

功能实现3:Can邮箱索引在接收报文中的使用

(额...,“邮箱索引的使用”,这不能算功能,但这个内容很重要)

首先,我们假设要实现1路CAN总线,且共有5条接收报文

我们都知道,报文是通过CAN控制器的CAN邮箱收上来的,在开发的时候,每条报文都必须配置对应的CAN邮箱。

对应方式可以一条报文对应一个CAN邮箱,即FullCAN。也可以多条报文对应一个邮箱,即BasicCAN。(关于FullCan和BasisCAN,这是属于CAN模块的内容,我们这里就不展开讲解了)

接下来,我们假设配置了3个接收邮箱。

CAN邮箱0(BasicCAN):接收2条报文(如:0x001,0x002)

CAN邮箱1(BasicCAN):接收2条报文(如:0x003,0x004)

CAN邮箱2(FullCAN):接收1条报文(如0x005)

我们前面说了,CanIf模块接收到报文后会轮询接收报文结构体数组hrh_rx_pdu_canif_hrh_cfg[ ],我们接收的5条报文的结构体数组如下示(代码省略部分内容)

于是,我们的问题就来了。

假设现在CAN模块收到了CAN报文的ID为0x005,然后送到了CanIf模块,如果我们不管CAN邮箱,直接轮询整个CanIf模块的接收报文结构体数组hrh_rx_pdu_canif_hrh_cfg[ ],如下图所示:

当然了,这里我们只有5条报文,报文少,轮询一下也没什么问题。

但是,如果情况变成这样:我们有100条报文要接收,Can邮箱0、Can邮箱1的报文加起来是99条,报文0x005还是在Can邮箱2里面,且还是只有1条

这种情况下,如果还是这样轮询,就实在太傻了,过于浪费时间了。

所以,为了避免这种情况,Can邮箱索引的作用就来了。

这个Can邮箱索引,是指每个Can邮箱都有1个对应的号码,即邮箱ID(邮箱ID从0开始递增),举例如下图所示:

然后,我们把CanIf模块定义好的每条接收报文,都对应上所属于CAN邮箱。

HaloOs它的实现方式如下:

使用“NofRxPdus“这个参数表示这个邮箱有多少条报文,再通过“RxPduList”这个参数指向接收报文结构体数组hrh_rx_pdu_canif_hrh_cfg[ ]中对应的首条报文。

于是,接收到Can模块在接收到CanId为0x005的报文后,由于是从Can邮箱2收上来的,且Can邮箱2是FullCan,只有1条报文。

因此,无论Can邮箱0、Can邮箱1有多少条报文,对于报文0x005来说,完全不用轮询数组,直接就能找到了CanIf模块报文结构体数组hrh_rx_pdu_canif_hrh_cfg[ ]所在的位置,如下图所示。

而如果Can模块在是接收到CanId为0x002的报文,由于Can邮箱0只有2条报文,则只需要轮询CanIf模块报文结构体数组hrh_rx_pdu_canif_hrh_cfg[ ]中的2个元素就可以了,如下图所示:

朋友们,这时候感受到Can邮箱Id的作用了吧。

我们再来看一下CanIf模块的标准接收接口:

从上图可以看到,CanIf_RxIndicaiton函数的参数里面就有报文对应的Can邮箱ID

朋友们,这就是为什么我们在工具链配置CanIf模块的接收报文时,接收报文要索引Can模块的Can邮箱(如下图所示)

功能实现4:接收报文为一段范围的CanId

接收一段范围的CanId这个功能一般情况下主要是用于接收Can网管报文

这个功能实际上很好理解,

比如Can网管报文ID范围为0x500-0x57F,我们不可能在CanIf模块定义0x500-0x57F中的每条报文吧?

因此,我们只需要在CanIf模块的报文结构体数组hrh_rx_pdu_canif_hrh_cfg[ ]中定义一个含CanIf范围的报文就可以了,如下图所示:

在接收到Can报文后,只需要判断一下Canid是否在指定的范围内即可。

对应的CanIf模块配置项如下图所示:

源码展示

在把我们上面讲的功能捋清楚后,我们再来看看源代码,这样就非常清晰了。

我们这里仅简单举例,具体大家可以去下载HaloOs的源码研究。

结语

大家有兴趣也可以打开Autosar工具链(HaloOs工具链)看看,与接收报文相关的功能与配置项,就是我们上面讲到的这些配置项,其实它没多少东西的。

下篇文章,我们继续讲解CanIf模块的功能。


 返回目录:

Autosar BSW 开发笔记(目录)-CSDN博客

http://www.dtcms.com/a/561036.html

相关文章:

  • 【Agentic RL 专题】三、深入浅出强化学习算法 TRPO 和PPO
  • 中国最好的建站公司毕业设计模板
  • 《算法通关指南:数据结构和算法篇 --- 栈相关算法题》--- 1. 【模板】栈,2.有效的括号
  • 高效管理搜索历史:Vue持久化实践
  • html网站架设目录和文章wordpress
  • Rust 编程语言基础知识全面介绍
  • 洛龙区网站制作建设费用做网站一般用什么语言
  • 计算机网络---基础诊断ping
  • 13.2.2.Nginx
  • java后端学习经验分享(大三进大厂版)
  • 好用的镜像源
  • 做网站的经验有什么好的加盟店项目
  • linux-shell-基础与变量和运算符-1
  • 论文解读:Sleeping with One Eye Open: Fast, Sustainable Storage with Sandman
  • 手机客户端网站建设腾讯云服务器免费领取
  • Gorm(十三)主从表的判断
  • 从零开始的云原生之旅(十):HPA 完全指南:从原理到实践
  • 注册网站费属于什么费用模板公司
  • MYSQL-多种方法安装部署
  • 做网站要学哪些代码上海资本公司排名
  • 认识多线程:单例模式
  • 深入解析 HarmonyOS 中 NavDestination 导航目标页的生命周期
  • 3、webgl 基本概念 + 绘制线段 + 绘制三角形
  • 【LeetCode热题100(58/100)】单词搜索
  • 旅行社网站模版网页设计六安模板
  • 求解器驱动智能决策新纪元
  • 简单网站制作成品广东省广州市佛山市
  • 使用 TransGPTex 将 LaTeX 英文论文翻译成中文:完整实战教程
  • APIJSON:用JSON自动生成API,告别手写CRUD!【.NET 8 集成案例,也支持JAVA】
  • 网络版本计算器