返回列表 发帖

[站长原创] Linux设备驱动类型 - 字符型设备驱动

[站长原创] Linux设备驱动类型 - 字符型设备驱动

嵌入式开发联盟www.mcuos.com

Osboy站长原创

QQ:82475491

Mcuos.com@gmail.com


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)初始化这个数据结构


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注册给内核


Linux提供了cdev_add函数对cdev数据结构进行内核注册。


(4)实现ops中的声明函数


我们需要根据您编写设备的特性对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提交您的编写代码,供大家研究哦!!!

分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友

使用内核提供的数据结构,然后初始化(设置函数指针指向自己的函数),再实现自己的函数

TOP

返回列表
网页右侧QQ悬浮滚动在线客服
网页右侧QQ悬浮滚动在线客服