|
[导读] 干过单片机的盆友或许都拿IO口对着时序模拟过SPI主控制器,在做嵌入式Linux设备开发时,发现SPI对应的脚都被用了,或者被当成别的用途了,这时候咋办?你或许会说我翻IO口写个字符驱动不就完了么?当然你可以这么做,然而并没有必要。自己写也挺麻烦且未必稳。憋慌!且看本文分解~SPI什么鬼? SPI(Serial Peripheral Interface) 是一种嵌入式系统中应用广泛的同步串行通信、主从架构式总线接口。80年代由摩托罗拉开发,已成为事实标准。 要理解啥是SPI,先上图,一图胜千言:
常见的SPI接口有这样几个引脚:
常见的两种总线连接方式, 方式一:独立片选
方式二:菊花链* b' N+ g7 c2 W ]% u$ Z
SCK/CS共用,数据线入出环形链接,bit流在SCK时钟作用下击鼓传花,逐次移位传递。! r! [9 b2 P$ E2 q 一图胜千言,看看我画的图吧:
前面说自己拿GPIO对着SPI收发时序波形去实现SPI字符设备有点重新造砖的嫌疑,且造出的砖兼容性、稳定性往往都差强人意。辣么,Linux下不这么干,可以怎么干呢? 首先用下面命令打开内核配置界面,来瞅瞅: make menuconfig% q N) m" D! \- G7 t稍等那么一会儿,熟悉的界面就出来了:
进入Device Drivers:
进入到SPI support,按Y选择:
完事之后,一顿退出保存配置,记得保存配置,别配置了半天没存哈。4 i' a2 t, I7 L( `1 i0 Q/ e. I 前面配置好了GPIO主控制器以及spidev设备驱动,然而如果直接编译,将内核部署到目标板上运行你发现啥也没有。那么还要做什么呢?你需要根据你的板子的情况配置哪些GPIO为SPI主控制对应的引脚!比如我用的ZYNQ,我这样配: spi {" U3 T, P- Z" K1 u3 F4 ]0 R) \compatible = "spi-gpio";5 o& H- g, B, ^- e9 v7 }) a #address-cells = <0x1>; ranges; 8 C2 z- M: G, N( j: S- n+ G" V! n# Q+ t sck-gpios = <&gpio0 7 0>; miso-gpios = <&gpio0 11 0>; mosi-gpios = <&gpio0 10 0>; cs-gpios = <&gpio0 12 0>; num-chipselects = <1>; /* 从设备clients */ device_0@0 { compatible = "spidev";/ z k) v$ f. S- a$ |7 Y+ n3 _ reg = <0>;8 l( j2 b( s8 ?# D3 h1 s t spi-max-frequency = <500000>;1 w4 B" t5 F. Q1 @; v# X H% l/ S #address-cells = <1>; #size-cells = <1>; spi-rx-bus-width = <1>; spi-tx-bus-width = <1>;4 y( L' `8 T. |/ B& l v' @ bits-per-word = <8>;# ^8 |" k& B" H };; g* V1 g* c9 ]) d$ l9 V7 _! S5 Q6 S }; 主控制器设备树:
从设备设备树:
设备树配置好后,编译加载到目标板上,此时在/dev下就会出现相应的设备 ,比如这样:
我配了好几个spidev,所以出现这么几个设备。 至于怎么从用户空间测试这些驱动,就是基本的文件open/read/write操作了,这里就不赘述了。 总结一下本文梳理了一下在SPI受限的情况下,Linux中GPIO用做SPI控制器的方法及实现,不用敲一行代码就妥了。把该驱的芯片就驱起来了。这里一个小的tips:
Linux发展至今,为啥能如此广泛应用,从这里也可见一斑。你大部分想到的需求,都基本给你造好了。拿来就用,一用就对!他不香么? ) I2 I% S' ^! q K' p5 {1 b |
微信公众号
手机版