当有一个spi device的时候,但是不想再内核态写spi_driver的话,可以使能CONFIG_SPI_SPIDEV
这样的话会生成一个spidev.ko ,插入这个ko后就可以在用户态open((“/dev/spidev0.0”), O_RDWR)的方式pen 这个设备
然后通过SPI_IOC_WR_MODE/SPI_IOC_RD_MODE 设置SPI_MODE_0,设置SPI_IOC_WR_BITS_PER_WORD/SPI_IOC_RD_BITS_PER_WORD为25000000,设置SPI_IOC_WR_MAX_SPEED_HZ/SPI_IOC_RD_MAX_SPEED_HZ 为25000000,最后就可以通过io(fd,SPI_IOC_MESSAGE(len),&spi),其中spi的类型为spi_ioc_transfer spi[len].来读写spi device。
这个驱动的实现在driver/spi/spidev.c中,这是个内核模块,其入口函数为
static int __init spidev_init(void)
{
int status;
/* Claim our 256 reserved device numbers. Then register a class
* that will key udev/mdev to add/remove /dev nodes. Last, register
* the driver which manages those device numbers.
*/
BUILD_BUG_ON(N_SPI_MINORS > 256);
status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);
if (status < 0)
return status;
spidev_class = class_create(THIS_MODULE, "spidev");
if (IS_ERR(spidev_class)) {
unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
return PTR_ERR(spidev_class);
}
#注册一个spi 驱动
status = spi_register_driver(&spidev_spi_driver);
if (status < 0) {
class_destroy(spidev_class);
unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
}
return status;
}
module_init(spidev_init);
static struct spi_driver spidev_spi_driver = {
#在spidev_init 中注册的驱动的name为spidev,也就是我们我们在用户态需要open的device,可以先通过ls /dev/spidev0.0
.driver = {
.name = "spidev",
.of_match_table = of_match_ptr(spidev_dt_ids),
.acpi_match_table = ACPI_PTR(spidev_acpi_ids),
},
.probe = spidev_probe,
.remove = spidev_remove,
/* NOTE: suspend/resume methods are not necessary here.
* We don't do anything except pass the requests to/from
* the underlying controller. The refrigerator handles
* most issues; the controller driver handles the rest.
*/
};
通过用户态驱动来读写spi 设备
猜你喜欢
转载自blog.csdn.net/tiantao2012/article/details/109132643
今日推荐
周排行