最近LZ接公司安排任务,移植一款CAN总线设备Mcp2515。由于在前次任务中有SPI经验,所以在接受任务是主要关注此设备采用SPI接口。所以一直没有关注CAN相关的知识,后续过程中遇到了不少麻烦,走了一些弯路。特把此次移植过程记录整理一下。
CAN总线是一种在汽车上广泛采用的总线协议,被设计作为汽车环境中的微控制器通讯。LZ理论知识有限,网上抄一句介绍的吧。如下:CAN(Controller Area Network)总线,即控制器局域网总线,是一种有效支持分布式控制或实时控制的串行通信网络。由于其高性能、高可靠性、及独特的设计和适宜的价格而广泛应用于工业现场控制、智能楼宇、医疗器械、交通工具以及传感器等领域,并已被公认为几种最有前途的现场总线之一。CAN总线规范已经被国际标准化组织制订为国际标准ISO11898,并得到了众多半导体器件厂商的支持。
我们的产品是作为CAN控制端,使用在一个电动汽车公司的汽车上的。该公司提供了单片机的终端设备进行通信调试。所以LZ这次任务还要写测试APK。这也是LZ第一次从APK到驱动的一次经验。使一次从上到下的经验,所以值得总结一下下。
此次调试是在EXYNOS4412三星四核CPU上,采用的是Android4.0.4文件系统和linux3.0.15的内核。是俺们公司的主打平台哦!吼吼!
调试开始了!
一.
电路信息
这是开发板的CAN小板图,从图上可知LZ需要连接的是VDD,CS,CLK,SI,SO,INT,RESET,VDD5.0几个pin。其中CS,CLK,SI,SO是SPI总线的常用的接口,是LZ比较熟悉的。其中SI连接MOSI控制气的发送口,SO连接MISO控制气的接收口。其他几个pin也是很容易明白的。INT中断pin,reset复位pin。在此LZ遗漏了一个严重的问题,导致后来驱动移植一直没有反应。就是LZ忽略了datasheet中的电源信息:
-工作电压范围2.7V至5.5V
- 5mA典型工作电流
Mcp2515的工作电压是2.7V至5V,这是适应了采用3.3V工作电压的CPU。但是LZ的4412的CPU采用的是1.8V。所以这里需要将上边的IOpin用1.8V转3.3V的电压转换IC进行转换。LZ后来在驱动调试中多次查问题无果后,重新仔细阅读了datasheet后才发现此问题。所以楼主在CPU与CAN设备之间添加了MAX3390E转换IC进行电压转换。
二.驱动移植
Mcp2515有标准的驱动,可以从网上找到下载,linux的内核里边也有默认的驱动。所以LZ只要配置好内核,添加设备端的配置信息就好了。以下是我的配置信息:
#ifdef CONFIG_CAN_MCP251X
static struct s3c64xx_spi_csinfo spi0_mcp251x_csi[] = { //spi总线CS片选pin配置
[0] = {
.line =EXYNOS4_GPB(1),
.set_level= gpio_set_value,
// .fb_delay =0x2,
},
};
static struct spi_board_info spi_mcp251x_board_info[] __initdata ={ //mcp251x设备信息
{
.modalias = "mcp2515",
.max_speed_hz = 6500000, //spi最大速率,配置为6500000
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0, //采用的是SPI0
.controller_data= &spi0_mcp251x_csi[0],
}
};
#endif
static void __init smdk4x12_machine_init(void) //内核的机器初始部分
{
struct device *spi_mcp251x_dev = &exynos_device_spi0.dev; //设备指针指向SPI0
……
……
#ifdef CONFIG_CAN_MCP251X
sclk =clk_get(spi_mcp251x_dev, "dout_spi0"); //spi总线时钟CLK配置
if (IS_ERR(sclk))
dev_err(spi_mcp251x_dev,"failed to get sclk for SPI-0\n");
prnt =clk_get(spi_m