您的位置:首页 > 其它

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

2017-06-09 17:30 176 查看
#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");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设备驱动
相关文章推荐