一、CDEV结构
|
二、file_operation 结构
|
三、为cdev申请内存
接下来,我们就需要为cdev申请内存,然后再通过cdev_init 函数将cdev与file_operation结构体联系起来,
|
最后通过cdev_add函数,将cdev添加到内核中
|
四、实例解析
1.自定义一个cdev结构体

如图所示,上述代码中,先自定义一个简单的cdev结构体key_dev,然后再实例化key_device, 接下来就定义一个我们接下来要操作的数组key_buff[MEM_SIZE],MEM_SIZE为自定义的内存的大小。
2.在init函数中初始化cdev结构体
当我们的应用程序调用open函数打开设备时,
在init函数中初始化cdev结构体,为cdev结构体开辟内存,连接cdev与fops结构体,注册cdev进入内核

3.一旦注册入内核,我们就可以开始使用了
当我们的应用程序打开设备时,在open函数中将filp的private_data赋值为我们所分配的key_device的结构体

4.释放cdev内存
当我们不用驱动时自然就要释放我们刚刚开辟的内存。
如图所示,首先删除cdev结构体,然后再使用kfree来释放cdev释放申请的内存

5.编译与测试

如图所示,我们在应用程序中先使用write函数往数组中写入'hello,Lover雪儿'的字符串,然后再使用read函数读取内容,但是,必须注意一点,在每次read后者write前,必须先使用lseek函数中重定位指针。

附上驱动程序源代码:
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 14 #define DEVICE_NAME 'cdev' 15 #define Driver_NAME 'key_cdev' 16 17 #define KEY_MAJOR 220 18 #define KEY_MINOR 0 19 #define COMMAND1 1 20 #define COMMAND2 2 21 #define MEM_SIZE 256 22 23 struct key_dev { 24 struct cdev cdev; 25 }; 26 struct key_dev *key_device; 27 static unsigned char key_buff[MEM_SIZE]; 28 29 //auto to create device node 30 static struct class *drv_class = NULL; 31 static struct class_device *drv_class_dev = NULL; 32 33 static int key_open(struct inode *inode,struct file *filp){ 34 filp->private_data = key_device; 35 return 0; 36 } 37 38 static int key_release(struct inode* inode,struct file *filp){ 39 return 0; 40 } 41 42 static ssize_t key_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos){ 43 ssize_t ret = 0; 44 loff_t pos = *f_pos; 45 if(pos > MEM_SIZE) //如果文件指针偏移超出文件大小 46 return ret = 0; 47 if(count > (MEM_SIZE - pos)) 48 count = 256 - pos; //若内存不足,则写到内存满的位置 49 pos += count; 50 //读出数据 51 if(copy_to_user(buf,key_buff + *f_pos,count)){ 52 return ret = -EFAULT; 53 } 54 *f_pos = pos; 55 return count; 56 } 57 58 static ssize_t key_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){ 59 ssize_t ret = -ENOMEM; 60 loff_t pos = *f_pos; //获取当前文件指针偏移 61 if(pos > MEM_SIZE) //如果文件指针偏移超出文件大小 62 return ret; 63 if(count > (MEM_SIZE - pos)) 64 count = 256 - pos; //若内存不足,则写到内存满的位置 65 pos += count; 66 //从fops处开始写入数据 67 if(copy_from_user(key_buff + *f_pos,buf,count)){ 68 ret = -EFAULT; 69 return ret; 70 } 71 *f_pos = pos; 72 return count; 73 } 74 75 static int key_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ 76 switch(cmd){ 77 case COMMAND1: printk('<0>ncommand 1 n'); break; 78 case COMMAND2: printk('<0>ncommand 2 n'); break; 79 default: printk('<0>command default n'); break; 80 } 81 return 0; 82 } 83 84 static loff_t key_llseek(struct file *filp, loff_t off, int whence){ 85 loff_t pos; 86 pos = filp->f_pos; //获取文件指针当前位置 87 switch(whence){ 88 case 0: pos = off; break; //重定位到文件开头
上一篇:IMX257 Linux内存空间内存分配
下一篇:【改进定时器】IMX257实现GPIO-IRQ定时器消抖驱动程序
推荐阅读最新更新时间:2026-03-24 10:48
- REF196 精密微功率、低压差堆叠电压基准的典型应用电路
- LTC4367IMS8 用于滞后调节的过压电源控制器的典型应用
- CLRC663非接触式读写器IC的典型应用
- 使用 ON Semiconductor 的 CS-5621 的参考设计
- RSO-0515S 15V、67mA输出DC/DC转换器典型应用电路
- NCP51200 3 Amp VTT 终端稳压器 DDR1、DDR2、DDR3、LPDDR3、DDR4 的典型应用
- LR645大电流SMPS启动电路典型应用
- ADR420 可编程电流源的典型应用
- DC417B,使用 LT1806CS8 多尺寸单运算放大器原型的演示板
- DM300019,用于评估 dsPIC30F 和 dsPIC33F MCU 系列器件的 dsPICDEM 入门开发板



嵌入式系统技术与设计
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号