Osboy觀點1:一種類型的驅動程序都有一個固定的數據結構來代表,然后我們要做的事情就是初始化這個數據結構,然后通過一個API注冊給內核,而對該設備進行讀寫等操作的函數在初始化這個結構體的過程中聲明過了,我們需要針對相應設備的特性實現這些讀寫函數,這就是編寫設備驅動我們需要做的事情,很簡單吧? 下面我們根據上述osboy的觀點來分析下字符型設備驅動如何編寫: (1)代表字符型設備驅動的數據結構:cdev 1. struct cdev { 2. struct kobject kobj; 3. struct module *owner; 4. const struct file_operations *ops; 5. struct list_head list; 6. dev_t dev; 7. unsigned int count; 8. }; (2)初始化這個數據結構 (3) Linux提供了cdev_init函數對cdev數據結構初始化。在初始化過程中,我們需要創建一個file_operations類型的結構體ops,類似于: 1. static const struct file_operations raw_fops = { 2. .read = do_sync_read, 3. .aio_read = generic_file_aio_read, 4. .write = do_sync_write, 5. .aio_write = blkdev_aio_write, 6. .fsync = blkdev_fsync, 7. .open = raw_open, 8. .release = raw_release, 9. .unlocked_ioctl = raw_ioctl, 10. .llseek = default_llseek, 11. .owner = THIS_MODULE, 12. }; 這個
raw_fops 初始化cdev中的ops。 (3)把這個cdev注冊給內核 (4)Linux提供了cdev_add函數對cdev數據結構進行內核注冊。 (4)實現ops中的聲明函數 (5)我們需要根據您編寫設備的特性對raw_fops中的函數實現。 .aio_read = generic_file_aio_read,
.write = do_sync_write,
.aio_write = blkdev_aio_write,
.fsync = blkdev_fsync,
.open = raw_open,
.release = raw_release,
.unlocked_ioctl = raw_ioctl, 上面這些函數都需要我們來實現,實現之后,驅動就編寫完成。是不是很簡單? Osboy觀點2:字符型設備驅動是linux設備驅動架構中最基本的一種驅動類型,很多大型的設備驅動,其實都根據字符型設備驅動進行的擴展,比如您在linux v4l2驅動中__video_register_device的函數中就能找到cdev字符型驅動的影子哦。 字符型驅動實例稍后給出,您也可以自己動手實踐,向osboy提交您的編寫代碼,供大家研究哦!!! 更多資訊可加交流群QQ277686564 QQ2905283896
|