吴旭华 发表于 2024-12-17 18:30:55

嵌入式驱动开发详解17(CAN驱动开发)

媒介

该专栏主要是讲解嵌入式干系的驱动开发,但是由于部分模块的驱动框架过于复杂,其内容量不是一个人能完成的,我们驱动开发职员主要是对其举行明白即可,所以本专栏对部分驱动代码干系内容不举行讲解,包括ALSA,Codec,CAN,USB,WIFI,4G模块等,这些只讲解干系的协议等基础知识
CAN简介

CAN 是如今应用非常广泛的现场总线之一,主要应用于汽车电子和工业领域,尤其是汽车 领域,汽车上大量的传感器与模块都是通过 CAN 总线连接起来的。CAN 总线如今是自动化领 域发展的热点技术之一,由于其高可靠性,CAN 总线如今广泛的应用于工业自动化、船舶、汽 车、医疗和工业装备等方面。
https://i-blog.csdnimg.cn/direct/e64070c23e834da89409f3c58b3f7b96.png
低速CAN是开环的,而高速CAN是闭环的,如下所示:
https://i-blog.csdnimg.cn/direct/028a4a7086364287814d86e15d7d9872.png
CAN 的全称为 Controller Area Network,也就是控制局域网络,简称为 CAN。CAN 最早是 由德国 BOSCH(博世)开发的,如今已经是国际标准(ISO 11898),是当前应用最广泛的现场总线 之一。BOSCH 主要是做汽车电子的,因此 CAN 一开始主要是为汽车电子准备的,事实也是如 此,CAN 协议如今已经是汽车网络的标准协议。如今除了汽车电子以外 也广泛应用于工业自动化、医疗、工业和船舶等领域。
https://i-blog.csdnimg.cn/direct/a6b0616a3eee4a7c970ed1c1aedbc5cf.png
同一 个 CAN 网络中所有单位的通信速度必须一致,差别的网络之间通信速度可以差别。图中 125Kbps 的 CAN 网络下所有的节点速度都是 125Kbps 的,整个网络由一个网关与其他的网络连接。
CAN 的特点:


[*]多主控制:所有单位都可以发送消息(多主控制),而两个以上的单位同时开始发送消 息时,根据标识符(Identifier 以下称为 ID)决定优先级。ID 并不是表示发送的目的地点,而 是表示访问总线的消息的优先级。
[*]体系的柔软性:与总线相连的单位没有类似于“地点”的信息。因此在总线上增加单位时,连接在总线上的别的单位的软硬件及应用层都不需要改变。
[*]通信速度快,距离远:最高 1Mbps(距离小于 40M),最远可达 10KM(速率低于 5Kbps),最新的 CAN-FD 最高速度可达 5Mbps/S,乃至更高。
[*]具有错误检测、错误通知和错误恢复功能:所有单位都可以检测错误(错误检测功能),检测堕落误的单位会立刻同时通知其他所有单 元(错误通知功能),正在发送消息的单位一旦检测堕落误,会逼迫结束当前的发送。逼迫结束 发送的单位会不停反复地重新发送此消息直到乐成发送为止(错误恢复功能)。
[*]故障封闭功能:CAN 可以判断堕落误的类型是总线上临时的数据错误(如外部噪声等)照旧持续的数据错 误(如单位内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将 引起此故障的单位从总线上隔离出去。
[*]连接节点多:CAN 总线是可同时连接多个单位的总线。可连接的单位总数理论上是没有限定的。但现实上可连接的单位数受总线上的时间延迟及电气负载的限定。降低通信速度,可连接的单位数增 加;提高通信速度,则可连接的单位数减少。
CAN收发器

CAN模块并不是直接通过控制器就能使用,还需要经过一个CAN收发器才气正常运行,如下所示没是SIT1050T芯片,芯片的一端连接控制器的CAN_TX和CAN_RX,别的一端连接CAN总线CAN_H和CAN_L:
https://i-blog.csdnimg.cn/direct/23b853e149084ec5b977996dd704c053.png
CAN协议讲解

电气特性

CAN 总线使用两根线来连接各个单位:CAN_H 和 CAN_L,CAN 控制器通过判断这两根线上的电位差来得到总线电平,CAN 总线电中分为显性电平和隐性电平两种。显性电平表示逻辑“0”,隐形电平表示 逻辑“1”。
https://i-blog.csdnimg.cn/direct/01fc4b4bbeb74f2387ca3be08b80e49f.pngCAN 总线上没有节点传输数据的时间一直处于隐性状态,也就是说总线空闲状态的时间一 直处于隐性。
传输协议

通过 CAN 总线传输数据是需要按照一定协议举行的,CAN 协议提供了 5 种帧格式来传输 数据:数据帧、遥控帧、错误帧、过载帧和帧隔断。其中数据帧和遥控帧有标准格式和扩展格 式两种,标准格式有 11 位标识符(ID),扩展格式有 29 个标识符(ID)。
https://i-blog.csdnimg.cn/direct/5a665ceb70af462284477a2bf1158acb.png
数据帧

接下来以数据帧为例举行讲解,数据帧包括以下内容:
①、帧起始,表示数据帧开始的段。
②、仲裁段,表示该帧优先级的段。
③、控制段,表示数据的字节数及保留位的段。
④、数据段,数据的内容,一帧可发送 0~8 个字节的数据。
⑤、CRC段,检查帧的传输错误的段。
⑥、ACK段,表示确认正常吸取的段。
⑦、帧结束,表示数据帧结束的段。
https://i-blog.csdnimg.cn/direct/946e5acb6c7b424386474b27c03425ba.png①、帧起始:帧起始很简单,标准格式和扩展格式都是由一个位的显性电平 0 来表示帧起始。
②、仲裁段:仲裁段表示帧优先级,仲裁段布局如下图所示,标准格式的 ID 为 11 位,发送序次是从 ID10 到 ID0,最高 7 位 ID10~ID4 不能全为隐性(1),也就是禁止0X1111111XXXXX如许的 ID。扩展格式的 ID 为 29 位,基本 ID 从 ID28 到 ID18,扩展 ID 由 ID17 到 ID0,基本 ID 与标准格式一样,禁止最高 7 位都为隐性。
https://i-blog.csdnimg.cn/direct/88af18e3795a4a31b85df65b4e3310a5.png


[*]CAN总线处于空闲状态,开始开始发送消息的单位获得发送权。
[*]多个单位同时开始发送时,从仲裁段(报文ID)的第一位开始举行仲裁。一连输出显性电平最多的单位可继承发送,即首先出现隐性电平的单位失去对总线的占有权变为吸取。如下图所示:
https://i-blog.csdnimg.cn/direct/f205b0c13eb14f48abf79a586e969a0d.png
③、控制段:控制段由 6 个位构成,表示数据段的字节数,标准格式和扩展格式的控制段略有差别,RTR是远程发送哀求位,显性电平0表示数据帧,隐性电平1表示扩展帧,在扩展帧中用SRR代替RTR,后面的RTR可以不用管;IDE是扩展标识符位,此位用于判断是标准帧照旧扩展帧; r0 为保留位,保留位必须以显性电平发送。DLC 为数据长度,高位在前,DLC 段有用值范围为 0~8。
④、数据段:数据段也就是帧的有用数据,标准格式和扩展格式雷同,可以包含 0~8 个字节的数据,从最高位(MSB)开始发送。
⑤、CRC段: CRC 段保存 CRC 校准值,用于检查帧传输错误,标准格式和扩展格式雷同,CRC 段由 15 位的 CRC 值与 1 位的 CRC 界定符构成。CRC 值的计算范围包括:帧起始、仲裁段、控制段、数据段,吸取方以同样的算法举行计算,然后用计 算得到的 CRC 值与此 CRC 段举行比较,如果不一致的话就会报错。
⑥、ACK段: ACK 段用来确认吸取是否正常,标准格式和扩展格式雷同,ACK 段由 ACK 槽(ACK Slot)和 ACK 界定符两部分构成。发送单位的 ACK,发送 2 个隐性位,而吸取到正确消息的单位在 ACK 槽(ACK Slot)发送显性位, 通知发送单位正常吸取结束,这个过程叫发送 ACK/返回 ACK。发送 ACK 的是所有吸取单位 中吸取到正常消息的单位,所谓正常消息是指不含添补错误、格式错误、CRC 错误的消息,这 些吸取单位既不处于总线关闭态也不处于休眠态的所有吸取单位中。
⑦、帧结束:最后就是帧结束段,标准格式和扩展格式雷同,帧结束段很简单,由 7 位隐性位构成。
遥控帧

吸取单位向发送单位哀求数据的时间就用遥控帧,遥控帧由 6 个段构成:
①、帧起始,表示数据帧开始的段。
②、仲裁段,表示该帧优先级的段。
③、控制段,表示数据的字节数及保留位的段。
④、CRC 段,检查帧的传输错误的段。
⑤、ACK 段,表示确认正常吸取的段。
⑥、帧结束,表示数据帧结束的段。
https://i-blog.csdnimg.cn/direct/f08e30fdf5d146e09de3717d535c0230.png
遥控帧布局基本和数据帧一样,最主要的区别就是遥控帧没有数据段。遥控帧的 RTR 位为隐性的,数据帧的 RTR 位为显性,因此可以通过 RTR 位来区分遥控帧和没有数据的数据帧。遥控帧没有数据,因此 DLC 表示的是所哀求的数据帧数据长度,遥控帧的其他段参考数据帧的形貌即可。
错误帧

当吸取或发送消息堕落的时间使用错误帧来通知,错误帧由错误标志和错误界定符两部分 构成,错误帧布局如图所示:
https://i-blog.csdnimg.cn/direct/36fb1747e8a14312b86fa4e7c04fa56f.png
错误标志有主动错误标志和被动错误标志两种,主动错误标志是 6 个显性位,被动错误标 志是 6 个隐性位,错误界定符由 8 个隐性位构成。
过载帧

吸取单位尚未完成吸取准备的话就会发送过载帧,过载帧由过载标志和过载界定符构成, 过载帧布局如图所示:
https://i-blog.csdnimg.cn/direct/1eb00ce74f5a43879241ffc71cfab558.png
过载标志由 6 个显性位构成,与主动错误标志雷同,过载界定符由 8 个隐性位构成,与错 误帧中的错误界定符构成雷同。
帧隔断

帧隔断用于分隔数据帧和遥控帧,数据帧和遥控帧可以通过插入帧隔断来将本帧与前面的 任何帧隔开,过载帧和错误帧前不能插入帧隔断,帧隔断布局如图所示:
https://i-blog.csdnimg.cn/direct/e315c3c386c04d87b15815a9760e7c44.png
隔断由 3 个隐性位构成,总线空闲为隐性电平,长度没有限定,本状态下表 示总线空闲,发送单位可以访问总线。延迟发送由 8 个隐性位构成,处于被动错误状态的单位 发送一个消息后的帧隔断中才会有延迟发送。
同步改正

https://i-blog.csdnimg.cn/direct/924a77594bdf49e09680793a10c00f13.png
这些段由 Tq(Time Quantum)构成,Tq 是 CAN 总线的最小时间单位。帧由位构成,一个位由4个段构成,每个段又由多少个 Tq 构成,这个就是位时序。1 位由多少个 Tq 构成、每个段又由多少个 Tq 构成等,可以恣意设定位时序。各段的作用和 Tq 数如图所示:
https://i-blog.csdnimg.cn/direct/17a89dfd40f74506afa0843e586644a3.png
CAN为了实现对总线电平信号的正确采样,数据同步分为硬件同步和再同步,首先是硬件同步,硬件同步是由控制器内部实现的,具体实现原理不详,但是总体调解方式如下:
https://i-blog.csdnimg.cn/direct/8a45c5db0a4c4cfe8787b20995dcb099.png
接下来是软同步,即再同步,再同步是通过调解SJW值来补偿PBS1或者PBS2的值,使SS到达正确的位置,再同步时,不能增加限定长度的SJW值。SJW值较大时,吸取误差
能力更强,但是通讯速度会降落。
CAN控制器

这里I.MX6ULL以为例举行讲解,实在STM32等芯片也是一样的逻辑,包含的功能和布局都是类似的,I.MX6ULL 带有 CAN 控制器外设,叫做 FlexCAN,FlexCAN 符合 CAN2.0B 协议。FlexCAN 完全符合 CAN 协议,支持标准格式和扩展格式,支持 64 个消息缓冲(STM32F407只有三级深度的两个吸取FIFO和三级发送邮箱),I.MX6ULL 的CAN 模块特性如下:
①、支持 CAN2.0B 协议,数据帧和遥控帧支持标准和扩展两种格式,数据长度支持 0~8 字 节,可编程速度,最高 1Mbit/S。
②、机动的消息邮箱,最高支持 8 个字节。
③、每个消息邮箱可以设置为吸取或发送,都支持标准和扩展这两种格式的消息。
④、每个消息邮箱都有独立的吸取掩码寄存器。
⑤、强大的吸取 FIFO ID 过滤。
⑥、未使用的空间可以用作通用 RAM。
⑦、可编程的回测模式,用于举行自测。
⑧、可编程的优先级组合。

CAN控制器模式

https://i-blog.csdnimg.cn/direct/6b7cb0b6b9b345029f395dbe30863d59.png
CAN吸取器

当总线上报文数据量很大时,总线上的装备会频仍获取报文,占用CPU。过滤器的存在,选择
性吸取有用报文,减轻体系负担。这里以stm32F407的过滤器为例,每个过滤器组都有两个32位寄存器CAN_FxR1和CAN_FxR2。一共有28个过滤器组,根据过滤器组的工作模式差别,寄存器的作用不尽雷同。位宽可设置32位或16位,寄存器存储的内容就有所区别,具体内容见下面三张图,第一副图阐明了存在屏蔽模式和标识符列表模式,第二副图阐明了如何过滤出符合条件的报文,最后一个图阐明了屏蔽模式是如何工作的。
https://i-blog.csdnimg.cn/direct/0099cba511974dfabbdd0608b2acc094.pnghttps://i-blog.csdnimg.cn/direct/d6d7723b9b38441191c99b51006926bb.png
https://i-blog.csdnimg.cn/direct/1635ee72bc604d198b0e917daa086e32.png
CAN波特率

最后就是CAN 波特率的计算了,这个地方的计算与前面的同步改正内容关联性比较大,这里照旧以stm32为例举行讲解,如下所示,tq是CAN 总线的最小时间单位,即时钟频率,通过1除以传输一个字节所需要的时间就可以算出波特率。通信双方波特率需要一致才气通信乐成。
https://i-blog.csdnimg.cn/direct/e34fe346165e40688b1ebe384ef26b90.png
CAN装备树分析

一样平常芯片原厂都会给用户写好CAN驱动并设置CAN节点,打开 Documentation/devicetree/bindings/net/can/ fsl-flexcan.txt,此文档形貌了I.MX6ULLFlexCAN 节点下的干系属性信息。跟之前一样在装备树里面设置好pinctl和完整节点信息即可,随后在linux内核的图形化设置界面打开CAN总线子体系(在linux下CAN总线是作为网络子体系的)和使能 Freescale 系 CPU 的 FlexCAN 外设驱动。
-------------------------------打开CAN总线子系统-----------------------------
-> Networking support ->
       <*> CAN bus subsystem support //打开 CAN 总线子系统
--------------------使能 Freescale 系 CPU 的 FlexCAN 外设驱动-----------------
-> Networking support
        -> CAN bus subsystem support
                -> CAN Device Drivers
                        -> Platform CAN drivers with Netlink support
                                -> <*> Support for Freescale FLEXCAN based chips //选中
CAN测试

CAN的驱动可以通过ifconfig -a查看,因为Linux 体系中把 CAN 总线接口装备作为网络装备举行同一管理。如果需要对CAN举行通信,可以使用can-utils工具举行测试,但是我们的根文件体系是通过 busybox 搭建,busybox自带的 ip 下令并不支持对 can 的操纵,因此我们需要重新移植 ip 下令,也就是 iproute2,这两个安装完成之后就可以举行测试了。一样平常情况下小工具和库的移植过程会有很多小细节需要注意。在移植 ip 下令的时间必须先对根文件体系做个备份!防止操纵失误导致体系启动失败!切 记!笔者的血泪履历教导!这里需要阐明一下,一样平常开发时直接选用buildroot创建根文件体系,因为他可以把一些小工具都直接一次性安装好,不需要跟busybox一样自己逐个搭建。
后续

本人对嵌入式行业爱好浓厚,但是发现驱动开发越学越迷茫,听有些up主驱动开发就算去芯片原厂或者模组原厂也是做缝缝补补或者移植的工作,一样平常需要要求对某一个领域,比如音频、网络、蓝牙等领域研究特殊深入才可能有能力做驱动开发工作,如今本人处于学习阶段,不太可能深耕某一个领域,因此当前阶段就仅仅只是了解驱动是如何实现底层工作的,后期可能会继承研究MCU的RTOS开发和Linux从bootloader->linux内核裁剪->驱动修改->应用开发,并将自己所学的皮毛用于开发一个小项目。
盼望对此方向感爱好的伙伴能一起批评交换!!!!
参考文献


[*]个人专栏系列文章
[*]正点原子嵌入式驱动开发指南
[*]瑞萨电子编写的《CAN 入门教程》
[*]对代码有爱好的同学可以查看链接https://github.com/NUAATRY/imx6ull_dev

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 嵌入式驱动开发详解17(CAN驱动开发)