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