最近由于接近放假,协调不到调板哥,于是兼职下调板的工作。虽然之前也业余玩过树莓派和arduino,但是由于没有stm32的开发经验和硬件知识的匮乏,还是遇到了很多坑。
这个can总线模块就卡了我两三天,由于涉及到树莓派的配置知识,觉得有必要记录一下。
can驱动配置
目前的这个项目涉及到了树莓派和stm32的通信,使用的是can总线。由于树莓派本身不提供can总线功能,需要外挂一个MCP2515芯片。
网上搜索树莓派的can总线配置,可以找到不少的资料,其中感觉最详细的是这一篇。但是里面有个小bug,我等下再说。
首先网上的接线多数都是这样的:
1 | RPi Pin RPi Label CAN Module |
然后修改文件/boot/config.txt激活MCP2515驱动:
1 | # 打开spi总线,树莓派与MCP2515之前通过spi通信,然后再转成can协议 |
这些dtoverlay配置项的说明可以查看/boot/overlays/README:
1 | ... |
所以以后需要打开什么功能,都可以到这文档里面查看配置方法。
首先由于我们把MCP2515 CAN控制器配到了spi0.0,所以我们需要配置spi0.0的cs脚(当然如果你也可以配置mcp2515-can1将它配置到spi0.1,这样的话就需要改spi0.1的cs脚)。
这个cs脚使是用来选择设备的,当有多个设备挂到spi总线上的时候可以用这个脚去选择指定设备。由于我们只有一个设备,所以可以使用spi0-1cs指定spi0只有一个cs脚,当然你也可以配置两个cs脚(spi0-2cs)留空一个不用。然后无论是spi0-1cs还是spi0-2cs,cs0默认都是gpio8,所以我们配不配都没有关系,下面几种配置方法都是对的:
- dtoverlay=spi0-1cs,cs0_pin=8
- dtoverlay=spi0-1cs
- dtoverlay=spi0-2cs,cs0_pin=8
- dtoverlay=spi0-2cs
- # 不配置,留空
之前我说的这一篇博客的小bug就是它配了dtoverlay=spi1-1cs,实际上是配置了spi1的cs脚,对我们的配置在spi0的can控制器没有影响
我们的接法和网上的不一样,INT脚接gpio17,CS脚接gpio22。根据文档修改下配置就好:
1 | dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=17 |
can驱动启动失败
事情到这里其实还算一帆风顺,我也没有花多少时间。但是当重启树莓派发现并没有/sys/bus/spi/devices/spi0.0/net/can0这个设备,使用dmesg命令查看开机日志会发现这样的一个错误,mcp2515驱动启动失败了:
1 | [ 7.653601] mcp251x spi0.0: MCP251x didn't enter in conf mode after reset |
然后我就懵逼了,网上搜索这个错误找到了很多遇到这种情况的人,但是他们的回答都是加上dtoverlay=spi0-1cs配置,让我一度怀疑自己的英语阅读水平以为自己文档看劈叉了(虽然水平的确也不怎样)。
由于我们的接线和网上的不一样,所以试了很多种配置都没有用。然后我们只能不断做尝试
让硬件帮忙跳线,跳到和网上的一样,然后用网上的配置 — 失败。
由于网上的例子都是用4.x的树莓派内核,而我们用的是5.x的内核。所以又猜测是系统版本原因,网上找了个旧的树莓派镜像验证 — 失败。
见到这篇博客说是电压问题,但是我用万用表量电压是5.17V,接近他所说的5.2伏 — 无用
找来示波器测量,发现cs脚在开机的时候的确有被拉低又拉高 – 排除树莓派gpio引脚的硬件问题
解决措施
就这样卡了两天,没有办法了在某宝上买了个用到mcp2515的模块回来验证(我们的板子是自己做的),发现买回来的是成功的。
那基本定位是硬件问题,于是交给硬件对比差异。经过修改引脚、晶振、最后定位到的确是电压问题,但是我们这边需要将电压改到3.3v才能用…
最后感慨几句。这段时间虽然遇到的大部分问题最终都定位到是硬件的问题。但是由于芯片都是买的,相当于一个黑盒,硬件修改也比较麻烦,所以需要软件先调试分析给出大概的定位。由于嵌入式经验不足,i2c、spi、can、i2s等各种硬件协议都只能现学现卖。嵌入式的api又由于需要考虑性能问题和应用层api侧重易用性的思路不一样,一堆配置和前置条件比较难用。每天都处于对自己能力的怀疑当中,不确定是否能做好,但所幸大部分问题都找到解决或者规避措施。也算去计算机的硬件底层瞄了几眼,开了不少眼界,算是给不平凡的鼠年画上了个特别的句号。希望明年还能继续保持对学习热情,有趣的东西那么多,为什么不去学呢?