大家好,今天主要和大家聊一聊,如何使用linux系统中SPI驱动ICM-20608六轴传感器的操作。
目录
第一:linux系统下SPI驱动框架简介
第二:SPI设备驱动编写
第三:SPI设备和驱动匹配过程
第一:linux系统下SPI驱动框架简介
SPI驱动框架分为主机控制器驱动和设备驱动,主机控制器就是SOC的SPI控制器接口。不管是什么SPI设备,SPI控制器部分的驱动都是一样的,重点就落在种类繁多的SPI设备驱动上了。
//SPI主机驱动就是SOC的SPI控制器驱动,linux系统中采用spi_master
struct spi_master{
struct device dev;
struct list_head list;
int (*transfer)(struct spi_device *spi, struct spi_message *mesg);
int (*transfer_one_message)(struct spi_master *master,struct spi_message *mesg);
.....
};
SPI主机驱动的核心就是申请spi_master,然后初始化spi_master,最后向linux内核注册spi_master。
第二:SPI设备驱动编写
linux内核使用spi_driver结构体来表示spi设备驱动,我们在编写SPI设备驱动的时候需要实现spi_driver。
struct spi_driver{
const struct spi_device_id *id_table;
int (*probe)(struct spi_device *spi);
int (*remove)(struct spi_device *spi);
void (*shutdown)(struct spi_device *spi);
struct device_driver driver;
};
spi_driver初始化完成以后需要向linux内核注册,spi_driver注册函数为spi_register_driver函数原型如下:
int spi_register_driver(struct spi_driver *sdrv)
sdrv:要注册的spi_driver
第三:SPI设备和驱动匹配过程
SPI设备和驱动的匹配过程是由SPI总线来完成的。
struct bus_type spi_bus_type = {
.name = "spi",
.dev_groups = spi_dev_groups,
.match = spi_match_device,
.uevent = spi_ueent,
};
采用设备树的情况下,SPI设备信息描述就通过创建喜迎的设备子节点来完成,可以打开设备树头文件,在此文件中找到对应的内容:
&ecspil{
fsl,spi-num-chipselects = <1>;
cs-gpios = <&gpio4 9 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
status = "okay";
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,m25p32";
spi-max-frequency = <20000000>;
reg = <0>;
};
};
SPI数据传输步骤如下:
1、申请并初始化 spi_transfer,设置 spi_transfer 的 tx_buf 成员变量,tx_buf 为要发送的数 据。然后设置 rx_buf 成员变量,rx_buf 保存着接收到的数据。最后设置 len 成员变量,也就是 要进行数据通信的长度。
2、使用 spi_message_init 函数初始化 spi_message。
3、使用spi_message_add_tail函数将前面设置好的spi_transfer添加到spi_message 队列中。
4、使用 spi_sync 函数完成 SPI 数据同步传输。
对于SPI设备驱动,首先就是要初始化并向系统注册spi_driver初始化,注册与注销代码如下:
/* 传统匹配方式 ID 列表 */
static const struct spi_device_id icm20608_id[] = {
{"alientek,icm20608", 0},
{}
};
/* 设备树匹配列表 */
static const struct of_device_id icm20608_of_match[] = {
{ .compatible = "alientek,icm20608" },
{ /* Sentinel */ }
};
/* SPI 驱动结构体 */
static struct spi_driver icm20608_driver = {
.probe = icm20608_probe,
.remove = icm20608_remove,
.driver = {
.owner = THIS_MODULE,
.name = "icm20608",
.of_match_table = icm20608_of_match,
},
.id_table = icm20608_id,
};
总结:linux系统中安装SPI驱动框架,可以编写出利用SPI通信协议的总线的通信过程,值得反复推敲。