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

server/2024/9/23 4:04:19/

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

• 分配内存空间函数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 30002.定义结构体:
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;


http://www.ppmy.cn/server/120615.html

相关文章

09年408考研真题解析-计算机网络

[题34]在无噪声情况下&#xff0c;若某通信链路的带宽为3kHz&#xff0c;采用4个相位&#xff0c;每个相位具有4种振幅的QAM调制技术,则该通信链路的最大数据传输速率是&#xff08;B&#xff09; A.12 kbps B.24 kbps C.48 kbps D.96 kbps 解析&#xff…

C++ | Leetcode C++题解之第415题字符串相加

题目&#xff1a; 题解&#xff1a; class Solution { public:string addStrings(string num1, string num2) {int i num1.length() - 1, j num2.length() - 1, add 0;string ans "";while (i > 0 || j > 0 || add ! 0) {int x i > 0 ? num1[i] - 0 …

基于JAVA的居家办公OA系统

使用Spring Boot来搭建一个基础的居家办公OA系统的一部分——例如一个简单的任务管理模块。这个例子将包括创建一个任务的功能&#xff0c;并且能够将任务保存到数据库中。为了简化起见&#xff0c;这里我们只展示核心代码片段&#xff0c;并假设已经设置好了Spring Boot项目环…

.net 之内存回收

前言 一些基本概念如下: 托管代码 托管代码就是执行过程交由运行时管理的代码。 在这种情况下&#xff0c;相关的运行时称为公共语言运行时 (CLR)&#xff0c;不管使用的是哪种实现&#xff08;例如 Mono、.NET Framework 或 .NET Core/.NET 5&#xff09;。 CLR 负责提取托…

TS React 项目中使用TypeScript

在 React 项目中使用 TS 创建新项目 在现有项目中添加 TS 创建新项目 命令&#xff1a;npx create-react-app my-app --template typescript 说明&#xff1a;在命令行中&#xff0c;添加 --template typescript 表示创建支持 TS 的项目 项目目录的变化&#xff1a; 在项目…

C语言:冒泡排序的注意事项及具体实现

一、注意事项 1、函数声明为&#xff1a;void bubble_sort(void* base, size_t num, size_t width, int (*cmp)(const void* e1, const void* e2)); 2、base 指向所要排序的数组 3、num 为数组的元素个数 4、width 为一个元素占多少个字节的空间 5、cmp 为函数指针&#xff0c;…

Java中stream流及Collectors的常见用法详细汇总!!!

目录 1. Stream流的优势 2. 常用用法 2.1 中间操作 2.1.1filter() 2.1.2 map() 2.1.3 sorted() 2.1.4 distinct() 2.1.5 limit() 2.1.6 skip() 2.2 终端操作 2.2.1 foreach() 2.2.2 collect() 2.2.3 reduce() 2.2.4 count() 2.2.5 anyMatch() 2.3 查找和匹配…

动态IP是如何实现的?

相信很多人都知道动态IP和静态IP的区别&#xff0c;但对于动态IP的实现过程或许还有些疑惑。那么接下来就为大家介绍一下动态IP的实现过程&#xff01; 动态IP的实现离不开一个关键协议&#xff0c;那就是DHCP。DHCP协议的主要任务就是在网络中自动分配IP地址&#xff0c;让设…