ARM驱动学习之9注册字符类设备

ARM驱动学习之9注册字符类设备

cpp 复制代码
• 分配内存空间函数kmalloc
-- 分配连续的虚拟地址,用于小内存分配。在include/linux/slab.h文件中。
-- 参数1:申请的内存大小(最大128K),
-- 参数2:GFP_KERNEL,代表优先权,内存不够可以延迟分配

• 分配内存空间函数kmalloc
-- 分配连续的虚拟地址,用于小内存分配。在include/linux/slab.h文件中。
-- 参数1:申请的内存大小(最大128K),
-- 参数2:GFP_KERNEL,代表优先权,内存不够可以延迟分配

• 字符设备初始化函数cdev_init
-- 在头文件include/linux/cdev.h中
-- 参数1:cdev字符设备文件结构体
-- 参数2:file_operations结构体
-- 注册设备本质是向linux设备文件中添加数据,这些数据需要初始化

/**
 * cdev_init() - initialize a cdev structure
 * @cdev: the structure to initialize
 * @fops: the file_operations for this device
 *
 * Initializes @cdev, remembering @fops, making it ready to add to the
 * system with cdev_add().
 */
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);
	cdev->ops = fops;
}

• 字符设备注册函数cdev_add
-- 在头文件include/linux/cdev.h中
-- 参数1:cdev字符设备文件结构体
-- 参数2:设备号
-- 参数3:设备范围大小
-- 向系统注册设备,也就是向linux系统添加数据

/**
 * cdev_add() - add a char device to the system
 * @p: the cdev structure for the device
 * @dev: the first device number for which this device is responsible
 * @count: the number of consecutive minor numbers corresponding to this
 *         device
 *
 * cdev_add() adds the device represented by @p to the system, making it
 * live immediately.  A negative error code is returned on failure.
 */
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
	p->dev = dev;
	p->count = count;
	return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
}

static void cdev_unmap(dev_t dev, unsigned count)
{
	kobj_unmap(cdev_map, dev, count);
}

• 卸载设备函数cdev_del
-- 参数1:cdev结构体
-- 移除字符设备
/**
 * cdev_del() - remove a cdev from the system
 * @p: the cdev structure to be removed
 *
 * cdev_del() removes @p from the system, possibly freeing the structure
 * itself.
 */
void cdev_del(struct cdev *p)
{
	cdev_unmap(p->dev, p->count);
	kobject_put(&p->kobj);
}


1.文件名和Makefile修改为register_cdev
头文件:
/*三个字符设备函数*/
#include <linux/stat.h>
/*MKDEV转换设备号数据类型的宏定义*/
#include <linux/kdev_t.h>
/*定义字符设备的结构体*/
#include <linux/cdev.h>
/*分配内存空间函数头文件*/
#include <linux/slab.h>

#define REGDEV_SIZE 3000

2.定义结构体:
struct reg_deg
{
    char *data;
    unsigned long size;
    struct cdev cdev;
};
struct reg_dev *my_devices;

my_devices = kmalloc(DEVICE_MINOR_NUM * sizeof(struct reg_dev),GFP_KERNEL);
if(!my_devices){
    ret = -ENOMEM;
    goto fail;
}
memset(my_devices,0,DEVICE_MINOR_NUM * sizeof(struct reg_dev));//初始化缓存为0;

for(i = 0;i < DEVICE_MINOR_NUM;i ++){
    my_devices[i].data = kmalloc(REGDEV_SIZE,GFP_KERNEL);
    memset(&my_devices[i],0,REGDEV_SIZE);
}

fail:
    unregister_chrdev_region(MDKEV(numdev_major,numdev_minor),DEVICE_MINOR_NUM);
    printk(KERN_EMERG "kmalloc is fail\n");
    
    return ret;
相关推荐
Y.9999 小时前
电脑黑屏只有鼠标能动
学习
架构师伯子明9 小时前
FFmpeg C++学习(一):编译和demo
开发语言·c++·学习
叼烟扛炮10 小时前
[LangChain] 学习笔记(02):LCEL 链式调用与动态模型配置实战
服务器·开发语言·网络·笔记·学习·langchain
程序员梅雨10 小时前
【从零开始学习数据仓库 | 第二篇】: 拉链表 & 数仓分层
大数据·数据仓库·学习
secondyoung10 小时前
Cortex-R52与TriCore详细对比
arm开发·单片机·嵌入式硬件·mcu
一木 之林10 小时前
Dify学习笔记 04 · 检索底座:Embedding、Rerank与向量数据库(第46-54集)
笔记·学习·embedding·dify
芯思路10 小时前
STM32开发学习笔记之十【AI部署】
笔记·stm32·学习
憧憬成为java架构高手的小白11 小时前
langgraph4j学习
学习
CCIE-Yasuo11 小时前
网络安全-学习web开发-列表、标签
前端·学习·web安全
旖旎夜光12 小时前
LeetCode 315: 算右侧小于当前元素的个数(归并排序) —— 题解
c++·学习·算法·leetcode·排序算法