RK3399PRO的字符spi设备驱动

别来无恙 提交于 2020-03-17 15:36:21

Linux 4.4内核SPI驱动特性:

①默认采用摩托罗拉SPI协议
②支持8位和16位
③软件可编程时钟频率和传输速率高达50MHz
④支持SPI 4中传输模式的配置
⑤每个SPI控制器支持一个到两个片选

1. 首先申请设备号(动态):

int alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name);

含义就是申请一个动态主设备号,并申请一系列次设备号。
baseminor为起始次设备号,count为次设备号的数量,name为设备名,会在设备/proc/devices创建同名设备。

实例:
alloc_chrdev_region(&devno, 0,255, "myOled"); // 申请设备号devno,直观看到就是“myOled”会在系统的/proc/devices内显示。
   
2.注册设备到系统(没有创建设备):

int cdev_add(struct cdev *p, dev_t dev, unsigned count)

含义为 cdev 结构的指针,起始设备编号,以及设备编号范围。

实例接上:
spidev_major = MAJOR(devno);//get allocated major number dynamicly,根据devno获取到主设备号。
cdev_add(&spicdev,MKDEV(spidev_major, 0),N_SPI_MINORS);// 注册字符串设备

 

3.创建设备类
struct class *class_create(struct module *owner, const char *name);

返回class结构体指针。传入模块owner,类名,注册进sysfs。会在sys/class/下创建对应name的类。

实例:

spidev_class = class_create(THIS_MODULE, "spidev");//create a class /sys/class/spidev



4.注册spi驱动到系统

int spi_register_driver(struct spi_driver *sdrv)

实例:
status = spi_register_driver(&spidev_spi_driver);

5.创建设备
struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...)
struct class *class -指定所要创建的设备所从属的类
struct device *parent - 是这个设备的父设备,若没有则指定为NULL
dev_t devt- 是设备号
void *drvdata- 设备回调函数携带参数
const char *fmt- 是设备名
实例:
dev = device_create(spidev_class, &spi->dev, spidev->devt, spidev, "myOled");

sysfs是linux2.6的虚拟文件系统,在设备模型中,sysfs文件系统用以表示设备的结构,将设备的层次结构反应到用户空间中,可通过修改sysfs中的文件属性来修改设备的属性值,挂载在"/sys"目录下。

整体就是内核中定义struct class结构体,一个struct class结构体类型变量对应一个类,内核同时提供class_create函数创建一个类,存放于sysfs下面,一旦创建好这个类,再调用device_create函数在/dev目录下创建相应的设备节点。而在加载模块时,用户空间中的udev daemon会自动响应device_create函数,去/sysfs下寻找对应的类来创建设备节点。

 




 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!