cdev_alloc和cdev_init 的使用
1.核心结构体定义:
struct cdev
{
struct kobject kobj; // 每个 cdev 都是一个 kobject
struct module *owner; // 指向实现驱动的模块
const struct file_operations *ops; // 操纵这个字符设备文件的方法
struct list_head list; // 与 cdev 对应的字符设备文件的 inode->i_devices 的链表头
dev_t dev; // 起始设备编号
unsigned int count; // 设备范围号大小
};
2.两种定义初始化方式:静态的(在stack中生成对象)和动态的(在heap中生成对象)。
静态内存定义初始化:
struct cdev my_cdev;//变量在stack中
cdev_init(&my_cdev, &fops);
my_cdev.owner = THIS_MODULE;
动态内存定义初始化:
struct cdev *ptr_my_cdev = cdev_alloc();//变量在heap中
ptr_my_cdev ->ops = &fops;
ptr_my_cdev ->owner = THIS_MODULE;
错误的定义初始化方式:
struct cdev *ptr_my_cdev = cdev_alloc();//变量在heap中
cdev_init(ptr_my_cdev , &fops);
ptr_my_cdev ->owner = THIS_MODULE;
错误原因分析:
相关函数源码如下:
struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p)
{
INIT_LIST_HEAD(&p->list);
kobject_init(&p->kobj, &ktype_cdev_dynamic);//ktype_cdev_dynamic用于指示cdev对象的产生方式是heap,销毁时要释放之。
}
return p;
}
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);//ktype_cdev_default用于指示cdev对象的产生方式是stack,销毁时不需要释放之。
cdev->ops = fops;
}
static void cdev_default_release(struct kobject *kobj)
{
struct cdev *p = container_of(kobj, struct cdev, kobj);
cdev_purge(p);
}
static void cdev_dynamic_release(struct kobject *kobj)
{
struct cdev *p = container_of(kobj, struct cdev, kobj);
cdev_purge(p);
kfree(p);//ktype_cdev_dynamic的特别之处
}
static struct kobj_type ktype_cdev_default = {
.release = cdev_default_release,
};
static struct kobj_type ktype_cdev_dynamic = {
.release = cdev_dynamic_release,
};
4.另类的定义初始化方式:
struct cdev my_cdev;//变量在stack中
struct cdev *ptr_my_cdev = &my_cdev;
cdev_init(ptr_my_cdev , &fops);
ptr_my_cdev ->owner = THIS_MODULE;
cdev_alloc和cdev_init 的使用相关推荐
- cdev_alloc和cdev_init
内核中每个字符设备都对应一个 cdev结构的变量,下面是它的定义: linux-2.6.22/include/linux/cdev.h struct cdev { struct kobject kob ...
- 《深入Linux设备驱动程序内核机制》中的mmap_demo.c例程
驱动代码如下: 1 #include <linux/module.h> 2 #include <linux/kernel.h> 3 #include <linux/typ ...
- 浅谈linux字符设备注册
Linux中有两种字符设备注册的方法: 这里所提到的函数在文件:fs/char_dev.c中定义,在头文件include/linux/cdev.h中声明. 一. 老方法: 如果 ...
- 驱动中的C语言----指针与指针初使化
在运用指针时,最多的错误就是指针的初始化.在程序中,一个未初始化的指针将会引起意想不到的问题.所以将指针初始化为NULL是个好习惯:在运用指针时,首先判断指针是否初始化,以防止指针指向一个未定义的地址 ...
- linux驱动开发:PWM驱动编写
要操控蜂鸣器,首先我们需要找到这个器件的原理图,从而找到芯片中控制这个器件的管脚,于是我们可以先去开发板的电路原理图中搜索该器件,找到原理图: 可以看到FS4412开发板使用了其中一路PWM输出(PW ...
- linux驱动开发5之字符设备驱动新接口
1.新接口与老接口 1)老接口:register_chrdev static inline int register_chrdev(unsigned int major, const char *na ...
- 驱动注册的两种方式(一)——file_operations结构体
使用file_operations结构体进行字符驱动设备的注册/注销: #include <linux/module.h> //module_init() & module_exi ...
- LV.11 嵌入式系统驱动初级
D1 背景.学习方法和环境搭建 计算机系统结构 程序分类 程序按其运行环境分为: 裸机程序:直接运行在对应硬件上的程序 应用程序:只能运行在对应操作系统上的程序 计算机系统的层次结构 无操作系统的简单 ...
- mtk cam_cal eeprom 驱动
文章目录 前言 1.驱动架构 1.1 结构目录 1.2 内核编译相关 1.3 Makefile 2.driver 2.1 init 2.1 EEPROM_drv_ioctl 2.2 EEPROM_ge ...
最新文章
- python怎么画小海龟_Python 海龟 turtle 画图实战任务(一):让小海龟留下Z字形的足迹以及绘制一个小于号<...
- 查找字符位置_Excel中查找字符第N次出现的位置信息,换个思路其实很简单
- 第三道深搜-----------hdu1016
- (转载) min()的宏定义中的(void) (_x == _y)的含义
- TensorFlow 2学习和工业CV领域应用 心得分享
- 华为荣耀30pro鸿蒙内测版,荣耀手机用户放心了 消息称荣耀30 Pro正在内测华为鸿蒙OS...
- ef sqlserver切换到mysql_可以为MySql和SqlServer使用EF上下文吗?
- python数据库查询系统_Python MySQL 查询数据(select from)
- 骚年快醒醒,你适合转行做前端吗?
- C# 编译器选项 /platform(指定输出平台)32位程序运行到x64平台的问题
- 三星手机微信聊天记录删除了怎么恢复
- iso22000食品安全管理体系_ISO22000-食品安全管理体系认证
- 任正非:华为云不能简单模仿阿里、亚马逊,要有所为有所不为|CEO说
- python打开网页后点击网页按钮_单击网页按钮的Python脚本
- sql日期格式转换函数_SQL转换日期函数和格式
- 开机出现invalid boot.ini filebooting from c:\windows\ntdetect failed 修复方法
- QQ快捷登录提示:禁止开发商强制用户重新注册或绑定其他帐号
- 机械振动信号15个时域统计指标
- SpringBoot在使用Security和JWT时,应当怎么放行图片等静态资源#访问静态资源#静态资源放行#报错401
- matlab画对数坐标!