23 类型的封装(内核里的继承)

来源:互联网 发布:衣服放久了有霉味知乎 编辑:程序博客网 时间:2024/05/21 16:59
#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/slab.h>#include <asm/uaccess.h>#define MYMA  1234#define MYMI  7788#define COUNT 1//为了方便重用和维护,把驱动所用到的数据封装成一个类型。typedef struct {    dev_t devid;    struct cdev mycdev;    u8 *data; //驱动数据缓冲区    int dlen; //驱动数据缓冲区长度}mydev_t;ssize_t myread(struct file *fl, char __user *buf, size_t len, loff_t *off){    struct cdev *cdev = fl->f_path.dentry->d_inode->i_cdev; //这里可能得到mydev_t对象的mycdev成员地址    mydev_t *dev = container_of(cdev, mydev_t, mycdev);//通过mycdev成员的地址得到mydev_t对象的首地址    int len_copy, ret;    if ((fl->f_pos + len) > strlen(dev->data))             len_copy = strlen(dev->data) - fl->f_pos;    else            len_copy = len;     ret = copy_to_user(buf, dev->data+fl->f_pos, len_copy);    *off += len_copy - ret;     return len_copy - ret;}struct file_operations fops = {    .owner = THIS_MODULE,    .read = myread,};mydev_t *dev;static int __init test_init(void){    int ret, i;    dev = kzalloc(sizeof(*dev), GFP_KERNEL);    dev->devid = MKDEV(MYMA, MYMI);    ret = register_chrdev_region(dev->devid, COUNT, "mydev");    if (ret < 0)        goto err0;    cdev_init(&(dev->mycdev), &fops);    dev->mycdev.owner = THIS_MODULE;    ret = cdev_add(&(dev->mycdev), dev->devid, COUNT);    if (ret < 0)        goto err1;    dev->dlen = 26;    dev->data = kzalloc(dev->dlen, GFP_KERNEL);     for (i = 0; i < 26; i++)         dev->data[i] = 'A' + i;    return 0;err1:    unregister_chrdev_region(dev->devid, COUNT);err0:    return ret;}static void __exit test_exit(void){    unregister_chrdev_region(dev->devid, COUNT);    cdev_del(&(dev->mycdev));    kfree(dev->data);    kfree(dev);}module_init(test_init);module_exit(test_exit);MODULE_LICENSE("GPL");