RK3568驅(qū)動(dòng)指南|第二篇 字符設(shè)備基礎(chǔ)-第12章 字符設(shè)備驅(qū)動(dòng)框架實(shí)驗(yàn)
瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工藝,搭載一顆四核Cortex-A55處理器和Mali G52 2EE 圖形處理器。RK3568 支持4K 解碼和 1080P 編碼,支持SATA/PCIE/USB3.0 外圍接口。RK3568內(nèi)置獨(dú)立NPU,可用于輕量級(jí)人工智能應(yīng)用。RK3568 支持安卓 11 和 linux 系統(tǒng),主要面向物聯(lián)網(wǎng)網(wǎng)關(guān)、NVR 存儲(chǔ)、工控平板、工業(yè)檢測、工控盒、卡拉 OK、云終端、車載中控等行業(yè)。
第12章 字符設(shè)備驅(qū)動(dòng)框架實(shí)驗(yàn)
下面對(duì)前面三個(gè)章節(jié)進(jìn)行總結(jié),首先驅(qū)動(dòng)向Linux內(nèi)核進(jìn)行設(shè)備號(hào)申請(qǐng),之后的字符設(shè)備注冊(cè)時(shí),會(huì)對(duì)申請(qǐng)的設(shè)備號(hào)進(jìn)行使用。而Linux 內(nèi)核會(huì)將字符設(shè)備抽象成一個(gè)具體的struct cdev結(jié)構(gòu)體,該結(jié)構(gòu)體記錄了字符設(shè)備的字符設(shè)備號(hào)、內(nèi)核對(duì)象等信息,cdev_init(…)函數(shù)對(duì)結(jié)構(gòu)體進(jìn)行初始化之后,cdev_add(…)函數(shù)將設(shè)備號(hào)和cdev結(jié)構(gòu)體進(jìn)行鏈接,這時(shí)設(shè)備號(hào)才真正指向了內(nèi)核中注冊(cè)的設(shè)備。設(shè)備注冊(cè)成功之后,此時(shí)還不能對(duì)字符設(shè)備進(jìn)行文件操作,所以需要設(shè)備節(jié)節(jié)點(diǎn)來充當(dāng)內(nèi)核和用戶層通信的橋梁,至此,前面三個(gè)章節(jié)就總結(jié)完成了,以上步驟并沒有涉及到操作設(shè)備文件,本章節(jié)將對(duì)字符設(shè)備框架進(jìn)行最終的完善。
12.1 文件操作集簡介
在進(jìn)行注冊(cè)字符設(shè)備實(shí)驗(yàn)章節(jié)中,使用cdev_init(…)函數(shù)對(duì)struct cdev結(jié)構(gòu)體類型變量和struct file_operations結(jié)構(gòu)體類型變量相鏈接,struct file_operations結(jié)構(gòu)體就是把系統(tǒng)調(diào)用和驅(qū)動(dòng)程序關(guān)聯(lián)起來的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。該結(jié)構(gòu)體的每一個(gè)成員都對(duì)應(yīng)著一個(gè)系統(tǒng)調(diào)用,讀取file_operation中相應(yīng)的函數(shù)指針,接著把控制權(quán)轉(zhuǎn)交給函數(shù),從而完成了Linux設(shè)備驅(qū)動(dòng)程序的工作。
file_operations結(jié)構(gòu)體定義在“內(nèi)核源碼/include/linux/fs.h”文件中,下面對(duì)部分常用函數(shù)進(jìn)行說明:
struct module *owner;
owner是第一個(gè) file_operations 成員,它并不是一個(gè)操作, 而一個(gè)指向擁有該結(jié)構(gòu)的模塊的指針,避免正在操作時(shí)被卸載,一般為初始化為THIS_MODULES (在 <linux/module.h> 中定義的宏)
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
read函數(shù)指針用來從設(shè)備中同步讀取數(shù)據(jù),讀取成功返回讀取的字節(jié)數(shù)。與應(yīng)用程序中的 read函數(shù)對(duì)應(yīng)。
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
write函數(shù)指針用來發(fā)送數(shù)據(jù)給設(shè)備. 寫入成功返回寫入的字節(jié)數(shù)。與應(yīng)用程序中的write函數(shù)對(duì)應(yīng)。
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
unlocked_ioctl函數(shù)指針提供對(duì)于設(shè)備的控制功能,與應(yīng)用程序中的ioctl函數(shù)對(duì)應(yīng)。
int (*open) (struct inode *, struct file *);
open函數(shù)指針用于打開設(shè)備,與應(yīng)用程序中的open函數(shù)對(duì)應(yīng)。
int (*release) (struct inode *, struct file *);
release函數(shù)指針在file結(jié)構(gòu)體釋放時(shí)被調(diào)用
至此對(duì)于file_operations文件操作集的部分常用函數(shù)就介紹完了,填充了部分常用函數(shù)的 file_operations結(jié)構(gòu)體如下(圖12-1)所示:
static struct file_operations cdev_fops_test = {
.owner = THIS_MODULE,//將owner字段指向本模塊,可以避免在模塊的操作正在被使用時(shí)卸載該模塊
.open = chrdev_open,//將open字段指向chrdev_open(...)函數(shù)
.read = chrdev_read,//將open字段指向chrdev_read(...)函數(shù)
.write = chrdev_write,//將open字段指向chrdev_write(...)函數(shù)
.release = chrdev_release,//將open字段指向chrdev_release(...)函數(shù)
};//定義file_operations結(jié)構(gòu)體類型的變量cdev_test_ops
會(huì)在下個(gè)小節(jié)進(jìn)行字符設(shè)備驅(qū)動(dòng)框架實(shí)驗(yàn)代碼的編寫,在上一章節(jié)實(shí)驗(yàn)的基礎(chǔ)上加入file_operations結(jié)構(gòu)體,并通過應(yīng)用程序?qū)ψ址O(shè)備驅(qū)動(dòng)進(jìn)行文件操作測試。
更多內(nèi)容可以B站搜索:迅為RK3568,關(guān)注公眾號(hào):迅為電子
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。