RK3399PRO的字符spi設備驅動

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

 




 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章