MCP2515在海思HI3531A平台上的驱动移植

最开始选择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。


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值