MCP2515在海思HI3531A平台上的驱动移植
最开始选择HI3531A,然后需要支持CAN设备以为是一件很简单的事情。本着一个Linux内核的老鸟心态,觉得应该这个是小儿科的东西。在网上搜索了一下发现很多人都有使用mcp2515的芯片,特别是还有某培训机构写了一篇很详细的文章,当时以为是一件简单的事情。然后打开Linux内核的源码,找到了mcp251x.c的文件,在头文件注释里面看到一段话:Your platform definiti
·
最开始选择HI3531A,然后需要支持CAN设备以为是一件很简单的事情。本着一个Linux内核的老鸟心态,觉得应该这个是小儿科的东西。在网上搜索了一下发现很多人都有使用mcp2515的芯片,特别是还有某培训机构写了一篇很详细的文章,当时以为是一件简单的事情。然后打开Linux内核的源码,找到了mcp251x.c的文件,在头文件注释里面看到一段话:
Your platform definition file should specify something like:
static struct mcp251x_platform_data mcp251x_info = {
.oscillator_frequency = 8000000,
.board_specific_setup = &mcp251x_setup,
.power_enable = mcp251x_power_enable,
.transceiver_enable = NULL,
};
static struct spi_board_info spi_board_info[] = {
{
.modalias = "mcp2510",
// or "mcp2515" depending on your controller
.platform_data = &mcp251x_info,
.irq = IRQ_EINT13,
.max_speed_hz = 2*1000*1000,
.chip_select = 2,
},
};
心想这个好简单,就是实现这两个结构体的定义。
结果这是噩梦的开始,海思根本没有按照spi的标准框架来实现。或是实现了我没看懂,所以纠结了很久。最后在spidev_info.c中找到了添加接口,结果还是不正常。然后各种调试使用示波器,后面发现是海思在实现上面有bug。修改好了能实现probe成功了。
probe成功后发现没法设置波特率,当然很多外面的文档都没用提到这个问题。关键问题是中断没法被初始化,所谓中断就是MCP2515的INT管脚需要接入到Linux内核通知线程中断函数注册:
ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
flags, DEVICE_NAME, priv);
if (ret) {
dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
if (pdata->transceiver_enable)
pdata->transceiver_enable(0);
close_candev(net);
goto open_unlock;
}
这个地方的问题其实很简单,主要解决的是中断沿的问题。需要把mcp2515的中断管脚拉到设备的IO中断口上来。然后在驱动注册的时候初始化外部中断。然后修改中断沿模式。这几个问题都解决了就可以正常识别mcp2515了。使用canuntil测试能正常send。
更多推荐
已为社区贡献5条内容
所有评论(0)