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