首先是spidev,要在/dev/下面产生设备文件,需要spidev的支持
使用的是gpio模拟spi,gpio模拟spi的时序原理是bitbang文件实现的,所以这个也需要打开,如果是在openwrt下动态加载的话就是如下两个配置
如果是直接内核的话是如下两个
跟I2C的arch层一样,主要是devices的添加和board_info的添加,如下
对于platform_add_devices,因为是使用spi_gpio,所以name是"spi_gpio"这样才可以与driver里面的spi_gpio相互匹配probe到。
因为SPI是可以一个总线上面挂多个,然后通过片选脚CS进行硬件切换,所以这变有个num_chipselect需要设置,如果有2个设置就设置2,一个设备就设置1,这边设置好之后,后面board_info也要有对应的个数,而且片选引脚需要不同。
I2C是通过每个设备有自己不同的地址,通过地址来进行软件切换。
对于board_info使用的是spidev,drivers/spi/spidev.c文件,该文件的内容是注册一个spidev驱动。该驱动是一个字符设备驱动。
如果设备与驱动匹配,那么就会执行spidev_probe()的内容。在spidev_probe()函数中会调用device_create()成功后在 /dev 目录下就会生成 spidev 相关的设备节点。
这边有几个参数要注意:
调试过程想看一些细节的debug信息可以打开内核的动态debug信息,这个在以前的print system里面有
printk的等级设置成8.
开始
定位到是 spi_gpio_request 的时候报错
后面就将zkernel/3.10.49/arch/mips/mtk/ziroom/zrmt7628.c里面GPIO的信息调整下, 因为SPI的引脚和LED的引脚号一样 ,内核不知道哪里会检测到。
修改后打印如下:
之后在/dev/下面就生成了spidev1.0的设备
有了/dev/spidev1.0设备之后,就可以在应用成 *** 作改设备收发数据。
在drivers/spi/spidev.c里面已经封装好了ioctl的对应接口,根据这些接口就可以测试使用。
在Documentation/spi/spidev_test.c下面有个应用层的实例,打开看下就清除了。
$(cc) spidev_test.c -o spidev_test生成可执行文件spidev_test
然后拷贝到板子上,将MOSI和MISO短接就可以测试回环数据是否正常。
有逻辑分析仪的接上logic看波形就更加直观。
gpio模拟SPI:
https://blog.csdn.net/luckywang1103/article/details/70145870
在ARM Linux下使用GPIO模拟SPI时序详解:
https://blog.csdn.net/yangzheng_yz/article/details/50470577
linux SPI驱动:
https://www.cnblogs.com/xuyh/category/903809.html
在<linux/spi/spi.h>头文件中包含有内核文档,做为主要的源码,你应该详读内核API文档的相关章节.本文只是概览,在了解细节前有个大致的图景是好的.SPI请求会进入到I/O队列中.请求给定的SPI设备也是按照FIFO顺序进行的,通过完成机制异步通知.也同简单的同步措施:先写在读出来.
有俩类SPI驱动:
控制器驱动(Controller drivers)...集成在SOC中的控制器,经常扮演Master和Slave双角色.这类驱动直接接触到硬件层的寄存器甚至使用DMA.亦或者扮演bitbanger,仅需要GPIO脚
协议驱动(Protocoldrivers)...在控制器和slave或者控制器和另外一条SPI链路上的Master传递消息.协议驱动是将控制器读到的数据,比如是一堆0,1代码,解析成有意义的协议数据
对于协议驱动应该是我们要写的,spi在linux内核中有spi子系统分为spi核心层,就类似USBcore一样是主控制器部分,另一个就是spi设备层了.前者内核帮咱写好了,为了让你的spi设备能工作,就得借助spicontroller driver导出的一些设施来编写protocoldrivers了.
struct spi_device结构封装了俩类驱动间的master-side接口.
有一个最小化SPI编程接口的core,专注于使用板级初始化代码提供的设备表并借助于驱动模型来连接controller和protocol驱动.在sysfs文件系统中,SPI视图:
1/sys/devices/.../CTLR ... physical node for a given SPI controller
2
3/sys/devices/.../CTLR/spiB.C ... spi_device on bus "B",
4 chipselect C, accessed through CTLR.
5
6/sys/bus/spi/devices/spiB.C ... symlink to that physical
7.../CTLR/spiB.C device
8
9/sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver
10 that should be used with this device (for hotplug/coldplug)
11
12/sys/bus/spi/drivers/D ... driver for one or more spi*.* devices
13
14/sys/class/spi_master/spiB ... symlink (or actual device node) to
15 a logical node which could hold class related state for the
16 controller managing bus "B". All spiB.* devices share one
17 physical SPI bus segment, with SCLK, MOSI, and MISO.
需要注意的是控制器类状态的实际位置取决于您是否开启CONFIG_SYSFS_DEPRECATED标志.此时,唯一的特定类状态是总线编号("B" in "spiB"),所以/sys/class下的那些入口项是唯一的识别总线的标志.
Linux中的SPI、IPC、USB等子系统都利用了典型的把主机驱动和外设驱动分离的想法,让主机端只负责产生总线上的传输波形,而外设端只是通过标准的API来让主机端以适当的波形访问自身。因此这里面就涉及了4个软件模块:1)主机端的驱动。根据具体的IC、SPI、USB等控制器的硬件手册, *** 作具体的IPC、SPI、USB等控制器,产生总线的各种波形。
2)连接主机和外设的纽带。外设不直接调用主机端的驱动来产生波形,而是调一个标准的API。由这个标准的API把这个波形的传输请求间接“转发”给了具体的主机端驱动。当然,在这里,最好把关于波形的描述也以某种数据结构标准化。
3)外设端的驱动。外设接在I-C、SPI、USB这样的总线上,但是它们本身可以是触摸屏、网卡、声卡或者任意一种类型的设备。我们在相关的i2c_driver、spi_driver、usb_driver这种xxx_driver的probe () 函数中去注册它具体的类型。当这些外设要求IP℃、SPI、USB等去访问它的时候,它调用“连接主机和外设的纽带”模块的标准API。
4)板级逻辑。板级逻辑用来描述主机和外设是如何互联的,它相当于一个“路由表”。假设板子上有多个SPI控制器和多个SPI外设,那究竟谁接在谁上面管理互联关系,既不是主机端的责任,也不是外设端的责任,这属于板级逻辑的责任。这部分通常出现在arch/arm/mach-xxx下面或者arch/arm/bootldts下面。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)