STM32MP157驱动开发——Linux CAN驱动
参考文章:【正点原子】I.MX6U嵌入式Linux驱动开发——Linux CAN驱动
CAN 是目前应用非常广泛的现场总线之一,主要应用于汽车电子和工业领域,尤其是汽车领域,汽车上大量的传感器与模块都是通过 CAN 总线连接起来的。上学的时候导师也说过,一个优秀的嵌入式工程师一定是一个优秀的 CAN 总线使用者。所以关于 CAN 总线的设计和驱动开发比较重要。本节就来学习一下开发板上的 CAN 接口驱动开发。
CAN 的全称为 Controller Area Network,也就是控制局域网络,以汽车电子为例,汽车上有空调、车门、发动机、大量传感器等,这些部件都是通过 CAN 总线连在一起形成一个网络。

在同一个 CAN 网络中所有单元的通信速度必须一致,不同的网络之间通信速度可以不同。CAN 的特点主要有以下几点:
- 1.多主控制
在总线空闲时,所有单元都可以发送消息(多主控制),而两个以上的单元同时开始发送消息时,根据标识符 (Identifier 以下称为 ID) 决定优先级。ID 并不是表示发送的目的地址,而是表示访问总线的消息的优先级。两个以上的单元同时开始发送消息时,对各消息 ID 的每个位进行逐个仲裁比较。仲裁获胜 (被判定为优先级最高) 的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。- 2.系统的柔软性
与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。- 3.通信速度快,距离远
最高 1Mbps (距离小于 40M),最远可达 10KM (速率低于 5Kbps),最新的 CAN FD 速度可以到 5Mbps。- 4.具有错误检测、错误通知和错误恢复功能
所有单元都可以检测错误 (错误检测功能),检测出错误的单元会立即同时通知其他所有单元 (错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止 (错误恢复功能)。- 5.故障封闭功能
CAN 可以判断出错误的类型是总线上暂时的数据错误 (如外部噪声等) 还是持续的数据错误 (如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。- 6.连接节点多
CAN 总线可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。
CAN 总线使用两根线来连接各个单元:CAN_H 和 CAN_L,CAN 控制器通过判断这两根线上的电位差来得到总线电平,CAN 总线电平分为显性电平和隐性电平两种。显性电平表示逻辑“0”,此时 CAN_H 电平比 CAN_L 高,分别为 3.5V 和 1.5V,电位差为 2V。隐形电平表示逻辑“1”,此时 CAN_H 和 CAN_L 电压都为 2.5V 左右,电位差为 0V。CAN 总线就通过显性和隐形电平的变化来将具体的数据发送出去。

总线空闲时,就一直处于隐形。并且CAN 总线两端要各接一个 120Ω 的端接电阻,用于匹配总线阻抗,吸收信号反射及回拨,提高数据通信的抗干扰能力以及可靠性。


CAN 协议提供了 5 种帧格式来传输数据,其中数据帧和遥控帧有标准格式和扩展格式两种,标准格式有 11 位标识符(ID),扩展格式有 29 个标识符(ID)。
各种数据帧的组成字段可参考原子哥教程中的描述。
CAN2.0 最高速度为 1Mbps / 秒。对于 CAN 总线,一个位分为 4 段:
① 同步段(SS)
② 传播时间段(PTS)
③ 相位缓冲段 1(PBS1)
④ 相位缓冲段 2(PBS2)
CAN FD 采用两种速率,控制段和仲裁段等使用标准的 CAN 速率,但是数据段会切换到更高的通信速率,比如 5Mbps。CAN FD 也对数据长度做了扩展,最大支持 64 字节。

改进:
1.增加一些控制位
EDL:用于指示当前为 CAN 帧还是 CAN FD 帧,标准 CAN 中此位为显性,在 CAN FD 中此位为隐性。
BRS:速率转换开关,为隐性的时候转换为可变速率,此时速率可变,BRS 到 CRC 之间使用可变速率。为显性的时候速率不变。
ESI:错误状态指示位,隐性的时候表示节点处于被动错误状态,显性的时候表示节点处于主动错误状态。
2.优化 CRC 算法
传统的 CAN 协议中,使用位填充的方式来保持同步,但是这种方法会对 CRC 造成干扰,导致错帧漏检。CAN FD 为此对 CRC 算法进行了优化,将填充位加入到差错校验码中进行计算,也就是以填充位的位流进行计算。
原理图:

CAN1_TX 和 CAN1_RX 是 STM3MP1 FDCAN 的发送和接收引脚,对应 STM32MP1 的 PH13 和 PI9 两个引脚。正点原子 STM32MP1 开发板上的 CAN FD 收发芯片有三种:MCP2562FDT、TJA1042T/3 或者 SIT1042T/3,这三种芯片 Pin to Pin 兼容,使用起来没有区别。SIT1042T/3为国产芯片,这里就以此为例进行开发。
R36 是一个 120 欧的端接匹配电阻。CAN_FD_STBY 是 SIT1042T/3 的高速与待机模式选择引脚,低电平为高速模式,连接在 PF12 引脚上,本节没有使用。
ST 原厂提供的设备树已经配置好了 FDCAN1 的节点信息,相关文档为 Documentation/devicetree/bindings/net/can/m_can.txt。在 stm32mp157-pinctrl.dtsi 文件中,存在 CAN 节点:

其引脚使用与开发板上的一致,所以不需要修改。
在 stm32mp153.dtsi 中,存在 m_can 节点:

根据 compatible 属性可以找到 STM32MP1 的 FD CAN 驱动源文件,为 drivers/net/can/m_can/m_can_platform.c。status 默认关闭。所以在自己的设备树中对其进行使能。在 stm32mp157d-atk.dts 中添加以下节点:
&m_can1 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&m_can1_pins_a>;
pinctrl-1 = <&m_can1_sleep_pins_a>;
status = "okay";
};
FDCAN1 两个状态的 pinctrl 节点分别为:m_can1_pins_a 和 m_can1_sleep_pins_a,并将 m_can1 节点的 status 属性改为“okay”,也就是使能 FDCAN1。
原子哥使用的教程中,ST官方对5.4.31版本的 CAN 驱动进行了维护,所以如果使用原子提供的内核源码,会出现不能进行收发数据的情况。可以从官方下载该版本的代码,或者使用原子哥提供的5.4.19版本驱动进行替换。即替换 m_can_platform.c 文件,位于源码目录下的 drivers/net/can/m_can/m_can_platform.c。
首先打开 CAN 总线子系统,在 Linux 下 CAN 总线是作为网络子系统的,在menuconfig中选中相应配置:


编译出新的内核镜像和设备树,然后启动开发板。
Linux 系统中把 CAN 总线接口设备作为网络设备进行统一管理,所有使用ifconfig -a命令查看所有网卡。

iproute2 是 Linux 上有关 TCP/IP 网络的一系列工具。需要此工具进行配置 CAN 网络
设备。
在 buildroot 的 menuconfig 中进行使能:

can0 网卡的收发测试需要使用 can-utils 工具,在buildroot中路径如下:

然后使用sudo make编译出新的根文件系统即可。
由于手头没有相应的转接线,所以就贴上相关命令和原子哥的图。
设置 CAN 接口速率:
ip link set can0 type can bitrate 1000000
设置 can0 速度为 1000Kbit / 秒,两个 CAN 设备的速度要设置为相同速率。
打开 can0 网卡:
ifconfig can0 up
接收数据命令:
candump can0
在上位机使用 USB 转 CAN 设备,然后就可以通过串口助手发送信息。

开发板发送信息:
cansend can0 5A1#11.22.33.44.55.66.77.88
cansend 命令用于发送 can 数据,“5A1”是帧 ID,“#”号后面的“11.22.33.44.55.66.77.88”就是要发送的数据,十六进制。CAN2.0 一次最多发送 8 个字节的数据,8 个字节的数据之间用“.”隔开。
关闭 can0:
ifconfig can0 down
CAN FD 的波特率最高为 1MBit/s,数据波特率为 5 MBit/s。
ip link set can0 up type can bitrate 1000000 dbitrate 5000000 fd on
ip link set can0 up type can bitrate 200000 dbitrate 1000000 fd on
ip link set can0 up type can bitrate 100000 dbitrate 500000 fd on
这是三种不同的速率设置,可以根据实际情况进行修改。
然后使用以下命令打开开发板的接收功能:
candump can0
从上位机发送数据,就可以在开发板接收到信息。
从开发板发送数据:
cansend can0 123##300.11.22.33.44.55.66.77.88.99.aa.bb.cc.dd.ee.ff.00.11.22.33.44.55.66.77.88.99.aa.bb.cc.dd.ee.ff.00.11.22.33.44.55.66.77.88.99.aa.bb.cc.dd.ee.ff.00.11.22.33.44.55.66.77.88.99.aa.bb.cc.dd.ee.ff
CAN FD 一次最多能收发 64 个字节的数据。
使用标准 CAN 进行收发测试时,可能会出现使用 500K 波特率时开发板接收有问题,这个问题需要修改 TF-A 下的 PLL4 频率。打开 TF-A 源码中的 fdts/stm32mp157d-atk.dtsi 文件:

修改cfg设置,配置方法可以参考 docs/devicetree/bindings/clock/st,stm32mp1-rcc.txt。
默认配置下 PLL4R=74.25MHz,修改后为 60MHz,也就是将 FDCAN 的时钟源设置为 60MHz。重新编译 TF-A,然后启动开发板即可。
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道rubyonrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,