Linux spi驱动 是一种 Linux 上的设备驱动,可以让操作系统识别通过SPI总线传输数据的设备。SPI是Serial peripheral interface(串行外围接口)的缩写。SPI接口提供时钟和两个双向数据线,它可以使得设备之间半双工或全双工传输数据。在这种接口下,通信双方可以保持实时通信,并可以通过特定的指令完成特定的功能。因此,具有SPI总线的设备在linux系统上普遍受到欢迎。
驱动的实现方式包括将开放的SPI驱动程序抽象为两个部分:spi_master和spi_device。前者定义了主设备的抽象包括设备的总线控制等;后者本质上是一个指向”spi_master”的抽象的指针,用以描述它的通信设备的特性和硬件信息,以便让Linux识别该设备。
Linux的SPI子系统通常位于arch/arm/mach-xxx/spi/文件夹中,主要由spi.h, spi_master.c, spi_driver.c等文件组成,分别定义了主设备和设备驱动的数据结构和函数。
具体实现方法如下:
1.在spi_init()函数中完成设备驱动的实例化,即创建spi_master结构实例;
2.在spi_probe()函数中完成设备驱动spi_device结构实例;
3.在spi_request()函数中完成spi_device实例的信息的初始化,并启动spi_driver进程;
4.在spi_write()函数中完成spi_device的写数据相关功能;
5.在spi_read()函数中完成spi_device的读数据相关功能;
6.在spi_remove()函数中完成spi_device的卸载。
int spi_init(struct spi_master *master)
{
int ret;
struct spi_device *spi;
ret = spi_register_master(master);
if (ret)
return ret;
list_for_each_entry (spi, &master->devices, list)
{
ret = spi_probe(spi);
if (ret != 0)
return ret;
}
return 0;
}
int spi_request(struct spi_device *spi, struct spi_config *config)
{
int ret;
//初始化spi_device信息
spi_fill_config(spi, config);
//启动spi_driver
ret = spi_start_driver(spi);
if (ret)
return ret;
return 0;
}
int spi_write(struct spi_device *spi, uint8_t *data, size_t len)
{
int ret;
ret = spi_do_transfer(spi, data, len, SPI_WRITE);
if (ret)
return ret;
return 0;
}
int spi_read(struct spi_device *spi, uint8_t *data, size_t len)
{
int ret;
ret = spi_do_transfer(spi, data, len, SPI_READ);
if (ret)
return ret;
return 0;
}
int spi_remove(struct spi_device *spi)
{
int ret;
ret = spi_stop_driver(spi);
if (ret)
return ret;
return 0;
}
我们已经掌握了Linux spi驱动的实现方法,掌握关键技能就是要精通主设备和设备驱动程序这两部分的抽象,即必须正确理解以上内容的每一步,并记住有关的代码、数据结构和函数,这样才能将SPI在Linux系统上实现得更加有效率。