淘宝上卖得最多的CAN模块就是基于MCP2515的CAN总线模块了,该模块通过SPI接口与MCU进行通信。RPi 2B/3B扩展口中包含SPI总线信号,可以很方便地对这个模块进行操作。这使得我们可以很方便地通过can-util工具获取CAN总线中的通信数据,当然也可以对CAN总线中的设备进行读写操作。
- MCP2515 CAN模块
1. 美图
(原图片来自: https://hacktronics.co.in/rs232485-usb-ttl-converters/mcp2515-can-bus-module-tja1050-receivers-spi-protocol)
2. 模块特点
- 支持CAN V2.0B规范,最大通讯速度可达到1Mb/S
- 一次可发送0 〜 8个字节数据,CAN总线每帧最多可发送8个字节
- 支持标准帧、扩展帧及远程帧
- 5V电源供电,使用SPI接口进行控制
- 120欧姆终端电阻
- 模块尺寸:4.4cm x 2.8cm
- 工作电流5mA
3. MCP2515
官网链接:http://www.microchip.com/wwwproducts/en/en010406
数据册:http://ww1.microchip.com/downloads/en/DeviceDoc/21801G.pdf
- RPi 2B与MCP2515 CAN模块
1. 连线
RPi 2B 40pin扩展口的定义请看这里:
引脚关系如下:
RPi 2B MCP2515_CAN -------------------------------------------------- P1-02 5V -> VCC 5V电源 P1-06 GND -> GND P1-24 GPIO8(CE0) -> CS P1-19 GPIO10(MOSI) -> MOSI P1-21 GPIO9 (MISO) <- MISO P1-23 GPIO11(SCLK) -> SCK P1-22 GPIO25 -> INT
- Raspbian系统操作方法
1. 修改开机脚本config.txt
dtparam=spi=on dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=25,spimaxfrequency=1000000
NOTE:
- kernel dt的配置与硬件紧密相连,要跟据硬件的实际情况进行设置
- 由MCP2515 datasheet可知,spimaxfrequency可设为10MHz
- 相关的说明文档详见/boot/overlays/README:
Name: mcp2515-can0 Info: Configures the MCP2515 CAN controller on spi0.0 Load: dtoverlay=mcp2515-can0,<param>=<val> Params: oscillator Clock frequency for the CAN controller (Hz) spimaxfrequency Maximum SPI frequence (Hz) interrupt GPIO for interrupt signal Name: mcp2515-can1 Info: Configures the MCP2515 CAN controller on spi0.1 Load: dtoverlay=mcp2515-can1,<param>=<val> Params: oscillator Clock frequency for the CAN controller (Hz) spimaxfrequency Maximum SPI frequence (Hz) interrupt GPIO for interrupt signal
由于原Raspbian系统运行时,在kernel log中与CAN、SPI相关的信息太少,可能在kernel log中只显示:
[ 1.422448] CAN device driver interface
再由于第一次在RPi 2B上使用该模块,并不清楚出现这个信息的时候,模块是否正常工作,加之将该模块的CAN接口接入总线的时候,得不到所需的信息。于是重新配置了kernel,打开了SPI与CAN 的debug信息,使得在kernel log中能够出现更多的调试信息,之后查看相关模块是否正常运行会在kernel log中出现如下信息:
pi@raspberrypi:~ $ dmesg | grep -i '\(can\|spi\)' [ 1.411356] spi-bcm2835 3f204000.spi: no tx-dma configuration found - not using dma mode [ 1.420102] spi-bcm2835 3f204000.spi: registered master spi0 [ 1.420318] spi spi0.0: setup mode 0, 8 bits/w, 1000000 Hz max --> 0 [ 1.420755] spi-bcm2835 3f204000.spi: registered child spi0.0 [ 1.420805] spi spi0.1: setup mode 0, 8 bits/w, 500000 Hz max --> 0 [ 1.421593] spi-bcm2835 3f204000.spi: registered child spi0.1 [ 1.422448] CAN device driver interface [ 1.422710] mcp251x spi0.0: setup mode 0, 8 bits/w, 1000000 Hz max --> 0 [ 1.432873] mcp251x spi0.0: CANCTRL 0x87 [ 2.026679] can: controller area network core (rev 20120528 abi 9) [ 2.026848] can: raw protocol (rev 20120528) [ 2.026873] can: broadcast manager protocol (rev 20120528 t) [ 2.026907] can: netlink gateway (rev 20130117) max_hops=1 [ 285.204945] mcp251x spi0.0 can0: bitrate error 33.3% too high [ 288.362092] mcp251x spi0.0 can0: bitrate error 0.7% [ 315.512812] mcp251x spi0.0: CNF: 0x00 0x88 0x01 [ 477.586754] mcp251x spi0.0 can0: bitrate error 33.3% too high [ 481.065628] mcp251x spi0.0 can0: bitrate error 66.6% too high [ 483.985830] mcp251x spi0.0 can0: bitrate error 77.7% too high [ 500.851264] mcp251x spi0.0: CNF: 0x01 0xb5 0x01 [ 640.260866] mcp251x spi0.0: CNF: 0x13 0xb5 0x01 [ 819.771295] mcp251x spi0.0 can0: bitrate error 33.3% too high [ 829.422866] mcp251x spi0.0 can0: bitrate error 33.3% too high [ 845.065217] mcp251x spi0.0: CNF: 0x00 0x91 0x01
当然,重新使用自己重新配置的kernel的另一个好处就是可以随时去修改mcp2515 driver的代码,以满足自己的需求。
2. 通过ip命令创建CAN网络设备,设置波特率为500kbps:
pi@raspberrypi:~/can-utils $ sudo ip link set can0 type can bitrate 500000 pi@raspberrypi:~/can-utils $ sudo ifconfig can0 up
这时我们可以使用ip命令查看CAN网络信息:
pi@raspberrypi:~/can-utils $ sudo ip -s -d link show can0
2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.750
tq 250 prop-seg 2 phase-seg1 3 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 4000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 3 3 0
RX: bytes packets errors dropped overrun mcast
224238 34273 12 0 12 0
TX: bytes packets errors dropped carrier collsns
0 0 0 0 0 0
3. 下载并安装can-utils:
$ git clone https://github.com/linux-can/can-utils.git $ cd can-utils $ make
4. 使用candump命令获取总线上的数据:
pi@raspberrypi:~/can-utils $ sudo ./candump -cae -t z can0,0:0,#FFFFFFFF (000.000000) can0 19D [8] 40 00 3F FF 10 00 00 FF '@.?.....' (000.000280) can0 1AF [3] 00 00 09 '...' (000.000546) can0 1F5 [8] 0F 0D 00 00 00 00 03 00 '........' (000.006001) can0 0C7 [4] 04 00 00 00 '....' (000.006259) can0 0F9 [8] 80 00 D0 00 00 00 00 00 '........' (000.006518) can0 199 [8] CF FF 47 2C B8 D1 00 FF '..G,....' (000.018526) can0 0C7 [4] 04 00 00 00 '....' (000.018782) can0 0F9 [8] 80 00 D0 00 00 00 00 00 '........' (000.019059) can0 199 [8] 0F FF 47 2C B8 D4 00 FF '..G,....' (000.024955) can0 19D [8] 80 00 3F FE 10 00 00 FF '..?.....' (000.025206) can0 1AF [3] 00 00 09 '...' (000.025536) can0 1F5 [8] 0F 0D 00 00 00 00 03 00 '........' (000.030997) can0 0C7 [4] 04 00 00 00 '....' (000.031290) can0 0F9 [8] 80 00 D0 00 00 00 00 00 '........' (000.031577) can0 199 [8] 4F FF 47 2C B8 D3 00 FF 'O.G,....' (000.043556) can0 0C7 [4] 04 00 00 00 '....' (000.043848) can0 0F9 [8] 80 00 D0 00 00 00 00 00 '........' (000.044140) can0 199 [8] 8F FF 47 2C B8 D2 00 FF '..G,....' (000.050000) can0 19D [8] C0 00 3F FD 10 00 00 FF '..?.....' (000.050306) can0 1AF [3] 00 00 09 '...' (000.050593) can0 1F5 [8] 0F 0D 00 00 00 00 03 00 '........'
5. 发送与接收
6. 路由及转发
待续
- 显示kernel模块mcp251x相关信息及参数的值
我们知道MCP2515对应的linux kernel module的名字为mcp251x,我们可以通过modinfo来查看这个模块的相关信息以及支持的参数列表,如:
pi@raspberrypi:/home $ modinfo mcp251x
filename: /lib/modules/4.4.11+/kernel/drivers/net/can/spi/mcp251x.ko
license: GPL v2
description: Microchip 251x CAN driver
author: Chris Elston <celston@katalix.com>, Christian Pellegrin <chripell@evolware.org>
srcversion: B646E18E95C132179C02575
alias: of:N*T*Cmicrochip,mcp2515*
alias: of:N*T*Cmicrochip,mcp2510*
alias: spi:mcp2515
alias: spi:mcp2510
depends: can-dev
intree: Y
vermagic: 4.4.11+ mod_unload modversions ARMv6
parm: mcp251x_enable_dma:Enable SPI DMA. Default: 0 (Off) (int)
从这里可以看到这个模块支持一个参数,这时如果我们想知道这个模块在当然运行的kernel对应的值,可通过systool这个命令查看,在raspbian系统中,这个工具需要安装:
$ sudo apt-get install sysfsutils
安装完后通过如下命令查看:
pi@raspberrypi:~ $ systool -vm mcp251x
Module = "mcp251x"
Attributes:
coresize = "9598"
initsize = "0"
initstate = "live"
refcnt = "0"
srcversion = "B646E18E95C132179C02575"
taint = ""
uevent = <store method only>
Parameters:
mcp251x_enable_dma = "0"
Sections:
.ARM.exidx.exit.text= "0xbf1195c4"
.ARM.exidx.init.text= "0xbf1195b0"
.ARM.exidx = "0xbf119504"
.ARM.extab.exit.text= "0xbf1195b8"
.ARM.extab = "0xbf119414"
.ARM.extab.init.text= "0xbf1195a4"
.bss = "0xbf119dc0"
.data = "0xbf119b80"
.exit.text = "0xbf1193d4"
.gnu.linkonce.this_module= "0xbf119be0"
.init.text = "0xbf11c000"
.note.gnu.build-id = "0xbf1193f0"
.rodata = "0xbf1195cc"
.rodata.str1.4 = "0xbf119a18"
.strtab = "0xbf11cab4"
.symtab = "0xbf11c024"
.text = "0xbf118000"
__mcount_loc = "0xbf119b30"
__param = "0xbf119b1c"
- 相关的参考文档:
- https://hacktronics.co.in/rs232485-usb-ttl-converters/mcp2515-can-bus-module-tja1050-receivers-spi-protocol
- http://qiita.com/mt08/items/535ab4690eecbcf5375d
- http://qiita.com/suzutsuki0220/items/8642b1c3ea51859a95ad
- http://qiita.com/suzutsuki0220/items/7cfdeb334efa4ffe3070