在Linux驅動中使用SPI(Serial Peripheral Interface)需要遵循以下步驟:
.config
)中啟用SPI子系統:CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_SLAVE=y
CONFIG_SPI_BIT_ORDER=msb
CONFIG_SPI_MODE=0
#include <linux/spi/spidev.h>
struct my_spi_device {
struct spi_device *spi;
// 其他私有數據
};
static int my_spi_probe(struct spi_device *spi)
{
struct my_spi_device *dev;
int ret;
dev = devm_kzalloc(&spi->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
dev->spi = spi;
spi_set_drvdata(spi, dev);
// 初始化SPI設備
ret = spi_setup(spi);
if (ret < 0) {
dev_err(&spi->dev, "Failed to setup SPI: %d\n", ret);
return ret;
}
// 其他初始化代碼
return 0;
}
static const struct spi_device_id my_spi_id[] = {
{ "my_spi_device", 0 },
{ }
};
MODULE_DEVICE_TABLE(spi, my_spi_id);
static struct spi_driver my_spi_driver = {
.driver = {
.name = "my_spi_device",
.owner = THIS_MODULE,
},
.probe = my_spi_probe,
.id_table = my_spi_id,
};
module_spi_driver(my_spi_driver);
在驅動程序中,你可以使用spi_transfer
函數來發送和接收數據。
static int my_spi_transfer(struct spi_device *spi, const void *tx_buf, void *rx_buf, size_t len)
{
struct spi_transfer tr = {
.tx_buf = tx_buf,
.rx_buf = rx_buf,
.len = len,
};
return spi_sync_transfer(spi, &tr, 1);
}
static int my_spi_receive(struct spi_device *spi, void *rx_buf, size_t len)
{
return my_spi_transfer(spi, NULL, rx_buf, len);
}
編譯驅動:
make -C /lib/modules/$(uname -r)/build M=$(PWD) modules
加載驅動:
sudo insmod my_spi_driver.ko
查看設備節點:
ls /dev/spidev*
編寫用戶空間程序來測試SPI通信。
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int fd = open("/dev/spidev0.0", O_RDWR);
if (fd < 0) {
perror("Failed to open SPI device");
return 1;
}
// 其他操作
close(fd);
return 0;
}
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main() {
int fd = open("/dev/spidev0.0", O_RDWR);
if (fd < 0) {
perror("Failed to open SPI device");
return 1;
}
char tx_buf[] = {0x01, 0x02, 0x03};
char rx_buf[3];
int ret = write(fd, tx_buf, sizeof(tx_buf));
if (ret < 0) {
perror("Failed to write to SPI device");
close(fd);
return 1;
}
ret = read(fd, rx_buf, sizeof(rx_buf));
if (ret < 0) {
perror("Failed to read from SPI device");
close(fd);
return 1;
}
printf("Received: ");
for (int i = 0; i < ret; i++) {
printf("%02X ", rx_buf[i]);
}
printf("\n");
close(fd);
return 0;
}
通過以上步驟,你可以在Linux驅動中使用SPI接口與外部設備進行通信。