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下尋找對應的類來創建設備節點。