SPI,MCP2515调试总结
转自http://www.xuebuyuan.com/2055253.html
MCP2515是一SPI转CAN总线的芯片,对于CPU来说,CPU就是主设备,SPI就是从设备,所以在内核里,MCP2515就是一个SPI设备,而SPI设备在内核中的结构是对应的,是一个spi控制器对应一个SPI设备,也就是一个spi_master对应一个spi设备,而SPI设备在内核中,尤其是新的内核中(新的内核越来越注重分层和分离的结构),则是在驱动中填充spi_driver驱动信息,在板载中填充spi_board_info信息.
要移植好SPI设备,有几点是要注意的.
1,make menuconfig中,CONFIG_SPI_S3C54XX和SPI_SPIDEV这两个及其相关的选项需要打开,因为第一个是spi控制器(驱动在dev-spi.c里),第二个就是SPI设备.
2,当然作为主角的MCP251x.c的驱动选项页当然要打开,内核中,MCP251X.C这个源码已经包含,在drivers/net/can下,检查下Makefile和Kconfig,然后menuconfig里打开编译选项,这一步大概也不会有什么问题.唯一要注意的是在此源码中,需要改一下DEVICE_NAME这个宏,要跟下面提到的modalias一致,因为这是用来match用的.
3,SPI控制器好了,SPI设备驱动有了,那就还差的是SPI控制器配置,SPI的设备信息等的填充了.在/arch/arm/mach-exynos/下的machine_init函数所在源码文件中添加填充
static struct s3c64xx_spi_csinfo spi0_csi[]=
//这个结构体用来设置片选引脚的
{
[0] = {
.line = //片选引脚
.set_level = gpio_set_value,
.fb_delay = 0x2,
},
};
static struct mcp251x_platform_data mcp251x_info
//这个结构体用来设置振荡器频率的,至于剩下的参数要不要设,需要具体看原理图的接线情况,头文件在
//\include\linux\can\platform\mcp251x.h
static struct spi_board_info spi0_board_info[]=
//这个结构体用来配置SPI设备,也就是对应MCP251X.c这个设备驱动用的,注意modalias要对上.
{
.modalias = ,
//要跟mcp251x.c上的DEVICE_NAME宏对上
.max_speed_hz = ,//CPU支持最高50MHz,但MCP2515芯片最高只支持到10MHZ,这里要好好权衡一下
.bus_num = ,
//SPI总线的选择,CPU提供3条SPI总线
.chip_select = ,//SPI总线上第几个设备的选择
.mode = SPI_MODE_0,//关于CPOL CPHA这2个值得选择,有4种模式 00 01 10 11
.platform_data = &mcp251x_info,//传给mcp251x.c驱动用的参数,就是上面的一个结构体.
.controller_data = &spi0_csi[0],//上面的一结构体,片选所用
.irq = ,//mcp2515芯片有一中断脚连到CPU,把复用后的中断量复制在此
}
这三个结构体填充完后(记得加上相应的头文件),就在static struct platform_device上添加初始化用的设备的变量exynos_device_spi的地址,这是给machine_init函数在添加这三个变量的时候用的,
struct clk *sclk = NULL;
struct clk *prnt = NULL;
struct device *spi0_dev = &exynos_device_spi0.dev;
sclk = clk_get(spi0_dev, "dout_spi0");
if (IS_ERR(sclk))
dev_err(spi0_dev, "failed to get sclk for SPI-0\n");
prnt = clk_get(spi0_dev, "mout_mpll_user");
if (IS_ERR(prnt))
dev_err(spi0_dev, "failed to get prnt\n");
if (clk_set_parent(sclk, prnt))
printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
prnt->name, sclk->name);
clk_set_rate(sclk, 10 * 1000 * 1000);
clk_put(sclk);
clk_put(prnt);
if (!gpio_request(片选引脚宏地址, 片选引脚名)) {
gpio_direction_output(片选引脚宏地址, 1);
s3c_gpio_cfgpin(片选引脚宏地址, S3C_GPIO_SFN(1));
s3c_gpio_setpull(片选引脚宏地址, S3C_GPIO_PULL_UP);
exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK,
ARRAY_SIZE(spi0_csi));
}
spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
而这里主要是注册SPI设备和SPI的时钟配置,配置好这些后正常的话就已经把mcp2515的can0设备驱动移植好了.
如果在这里出了问题,不防先设置好spidev.c的驱动,先调好spi的控制器,再把spidev替换成mcp2515.
4,CAN总线在新版本的内核中,并不是以字符设备的形式出现的,原因内核也有说明,主要是因为内核把CAN设备看成了网络设备(当然由于CAN设备的特殊性,CAN是没有IP地址可言的),需要用到socketcan协议,所以要想运行CAN总线,那么就要再menuconfig上打开can的协议(打开项在Networking support-->CAN bus subsystem support下).
5,内核部分完成后,就到Android部分了,由于不是字符设备,不能对其进行简单的读写操作,所以要用到2个工具,iproute2 和 canutil
iproute2在安卓源码上就有,external/iproute2,
而canutil则在网上可以下到,而是用canutil内的命令,还需要用到libsocketcan的库.
调试总结:
在刚开始调试的时候,spi在内核中的框架并不熟悉,困惑于spidev.c和mcp251x.c之间的关系怎么处理,spi的设备怎么设置时钟,为什么mcp251x.c驱动调出来之后再spi下的目录里没有mcp251x的字符设备可供调用等等.
其实spidev跟mcp251x是处于同一位置的spi设备,都由spi控制器控制,或许是可以在spi0_board_info结构体填充chip_select的时候填上排序的序号,可是最后没有用上,因为spidev不是一个实质的设备.而spi下没有mc251x的字符设备供调用是因为mcp251x的驱动节点在net/can0里,意味着内核把它注册为网络设备.这里在调试的时候最好还是先用spidev来先调好spi控制器,因为spidev的驱动提供了可调用的 spi下的字符设备节点,而在内核中,已经提供了spi设备的测试代码在document/spi下,在编译好后放到开发板上,并将spi发送接收的2条线接上,那么正常的情况下spi就能实现自收自发,这时再去调试mcp251x.c的驱动,就可以不用担心spi在系统上出太大问题了(不过关于时钟这一部分,需要好好地配置).
然后再测试can接口的时候,iproute2这个工具出现过bitrate这个参数无法辨认的情况,其实是在iproute2/ip目录下对iplink_can.c并没有实际调用,归根到底,是在编译android的时候,某些iplink_can.c内某些头文件没有顺利调用导致最后ip命令的参数不支持can,最后吧头文件的include写成了相对地址来调用,就可以了.
而对于canutil这个工具,要顺利编译好,也经过了一些波折,自己用的编译器比较多,环境变量不全,是个挺麻烦的问题,最后自己添加了环境变量,同时无视了伯克利相关的库后,勉强编译成功了cansend candump canecho和cansequence四个工具去调用.
现在,使用ip link set can0 type can bitrate xxx这些命令来设置波特率,用cansend和candump来发送接收,能用示波器看到波形了,但是数据在接收那边还没能出来,这个在之后得后续更新原因.
6、本文主要验证Linux-imx_share\Documentation\spi目录下spidev_test.c的测试例程,能否正常控制SPI接口。在命令行下输入ifconfig -a,已经出现can0信息
SPI,MCP2515调试总结相关推荐
- RK3288平台 SPI接口调试步骤
RK3288平台 SPI接口调试步骤 代码路径 drivers/spi/spi.c spi驱动框架 drivers/spi/sp ...
- MCP2515调试笔记----初始化注意事项
在调试基于F103单片机的MCP2515时,怎么调试都不正常,用的还是以前调试过的代码,隔了一段时间后再重新运行就不行了: 于是单步运行调试,没想到,单步运行调试竟然成功了:于是想到是延时的问题,在初 ...
- SPI/I2S调试心得与经验总结
一.调试中首先检查SPI使能总线是否正确: 检查时序(现有时钟,后片选拉低),接收时必须有发送才能有时钟 二.对照flash芯片手册查看SPI时序 三.检查状态位 1.查询标志位: 1)while(S ...
- (30)SPI接口调试丢数据解决(FPGA不积跬步101)
1)遇到问题 FPGA与微处理器进行数据交互用到了SPI接口总线,SPI总线已经很成熟了,网上也有好多开源代码.但是,项目开发调试中也遇到SPI通信丢帧验证问题. 2)解决方法 a.设计思路为:SPI ...
- android spi串口调试,PIC入门3,SPI通信和串口调试实验
原标题:PIC入门3,SPI通信和串口调试实验 MSSP模块工作于SPI主控方式,这个可以直接在实验板上执行. 程序: //适合3EPIC实验板,配置PIC的MSSP模块工作于SPI主控方式下, // ...
- STM32环境下AS5048A14位磁旋转编码器SPI通讯调试记录——我学到的东西、遇到的问题、解决的过程
❤ 2019.3.16 事情是这样的. 在很多天以前,老师接了个项目,问我有没有意向,我谨慎的表达了我对新事物的好奇心,对新知识的求知欲,同时又委婉的表达了我的能力有限的实际情况,然后我以为事情就这么 ...
- rv1126平台spi屏调试
我们使用的rv1126平台,屏ic ST7789,硬件使用6bit,由于不是8bit的,所以显示的颜色没有那么丰富 1.硬件原理图 2.dts配置 &rgb {status = "o ...
- BF609 CCES下的SPI驱动调试--就这样被它折磨了一周
在CCES环境下,ADI 自带了驱动接口函数,为驱动调试省下一大杯子事:但是这为人熟知的SPI,在调试过程中还是遇到了挫折,几度想撞墙: 最大的折磨:死机. 实际的SPI驱动接口是全双工功能的,所以传 ...
- MCP2515调试经验01
MCP2515有三个CAN发送缓冲区,可以通过TXBnCTRL中的TXP[1:0]配置 发送优先级,当两个或者3个缓冲区配置相同优先级时,拥有最大缓冲区编号的缓冲区优先发送.这可能造成缓冲区0的消息发 ...
最新文章
- 达沃斯议程对话会:张亚勤解读人工智能发展 3R 原则
- tensorflow中Tensorboard的用法
- 毕业设计:基于Springboot实现求职招聘,校园招聘系统
- Hadoop组件基本操作
- 学习笔记(3.23)
- storm 动态设置并发度
- MySQL数据库备份工具mysqldump的使用(转)
- 汇编语言-010(循环移位ROL,ROR 、进位循环进位RCL,RCR 、有符号数溢出 、双精度移位SHLD,SHRD、SHL和ADD计算 、位运算应用)
- Spring Boot(十四):spring boot整合shiro-登录认证和权限管理
- Python学习---Django的基础操作180116
- Array.of()方法
- 35 岁财务自由的小马哥,我想跟他学学!
- 计算机三级嵌入式系统易错题总结
- 腾讯没有梦想,阿里没有盟友?
- python语法学习第七天--文件
- Axure9桌面无法显示图标
- window下ruby的下载与gem安装
- 网络随堂笔记2(计算机网络下三层硬件及拓扑结构)
- Unity 实现简单的人物对话系统
- U盘安装Linux系统