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