SPI(Serial Peripheral Interface) 是一种嵌入式系统中应用广泛的同步串行通信、主从架构式总线接口。80年代由摩托罗拉开发,已成为事实标准。
要理解啥是SPI,先上图,一图胜千言:
常见的SPI接口有这样几个引脚:
常见的两种总线连接方式,
每个从设备都有独立的片选引脚,主机同一时间段内,与一个从设备进行通信,也即选中一个从设备,其他线并接共用
SCK/CS共用,数据线入出环形链接,bit流在SCK时钟作用下击鼓传花,逐次移位传递。
一图胜千言,看看我画的图吧:
前面说自己拿GPIO对着SPI收发时序波形去实现SPI字符设备有点重新造砖的嫌疑,且造出的砖兼容性、稳定性往往都差强人意。辣么,Linux下不这么干,可以怎么干呢?
首先用下面命令打开内核配置界面,来瞅瞅:
make menuconfig
稍等那么一会儿,熟悉的界面就出来了:
进入Device Drivers:
进入到SPI support,按Y选择:
完事之后,一顿退出保存配置,记得保存配置,别配置了半天没存哈。
前面配置好了GPIO主控制器以及spidev设备驱动,然而如果直接编译,将内核部署到目标板上运行你发现啥也没有。那么还要做什么呢?你需要根据你的板子的情况配置哪些GPIO为SPI主控制对应的引脚!比如我用的ZYNQ,我这样配:
spi {
compatible = "spi-gpio";
#address-cells = <0x1>;
ranges;
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";
reg = <0>;
spi-max-frequency = <500000>;
#address-cells = <1>;
#size-cells = <1>;
spi-rx-bus-width = <1>;
spi-tx-bus-width = <1>;
bits-per-word = <8>;
};
};
主控制器设备树:
从设备设备树:
设备树配置好后,编译加载到目标板上,此时在/dev下就会出现相应的设备 ,比如这样:
我配了好几个spidev,所以出现这么几个设备。
至于怎么从用户空间测试这些驱动,就是基本的文件open/read/write操作了,这里就不赘述了。
本文梳理了一下在SPI受限的情况下,Linux中GPIO用做SPI控制器的方法及实现,不用敲一行代码就妥了。把该驱的芯片就驱起来了。这里一个小的tips:
当面临要写驱动的时候,先查查是否已经有现成的实现,鼓捣鼓捣就能用岂不是妙!
Linux发展至今,为啥能如此广泛应用,从这里也可见一斑。你大部分想到的需求,都基本给你造好了。拿来就用,一用就对!他不香么?
最近较忙,原创不易,在看/点赞/转发支持一波可好~~~