欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > Rk3568驱动开发_完善字符驱动_4

Rk3568驱动开发_完善字符驱动_4

2025/3/1 15:47:45 来源:https://blog.csdn.net/xyint/article/details/145864409  浏览:    关键词:Rk3568驱动开发_完善字符驱动_4

1.代码

驱动代码:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>#define CHREDEVBASE_MAJOR 200  // 主设备号
#define CHRDEVNAME  "chrdevbase"  // 名字static char kernaldata[20] = {"kerndata"};static int chrdevbase_open(struct inode* inode, struct file* filp){printk("chrdevbase_open\r\n");return 0;
}static int chrdevbase_release(struct inode* inode, struct file* filp){//printk("chrdevbase_release\r\n");return 0;
}static ssize_t chrdevbase_read(struct file* filp, __user char* buf, size_t count, loff_t* ppos){int ret = 0;// 应用程序不能直接访问内核,必须借助其他函数ret = copy_to_user(buf, kernaldata, count); // 将内核数据copy到用户if(ret < 0){printk("copy to user error\r\n");return -1;}                             //printk("hrdevbase_read\r\n");return 0;                
}static ssize_t chrdevbase_write(struct file* filp, const char __user *buf, size_t count, loff_t* ppos){//printk("chrdevbase_write\r\n");int ret = 0;ret = copy_from_user(kernaldata, buf, count);if(ret < 0){printk("copy from user error\r\n");return -1;}printk("write msg is %s\r\n", kernaldata);return 0;
}// 字符设备操作集合
static struct file_operations chrdevbase_fops={.owner = THIS_MODULE,       // 属于这个驱动模块.open = chrdevbase_open,.release = chrdevbase_release,.read = chrdevbase_read,.write = chrdevbase_write,
};static int __init chrdevbase_init(void){   int ret = 0;printk("chrdevbase_init\r\n");// 注册字符设备ret = register_chrdev(CHREDEVBASE_MAJOR, CHRDEVNAME, &chrdevbase_fops);if(ret < 0){printk("chrdevbase init failed\r\n");unregister_chrdev(CHREDEVBASE_MAJOR, CHRDEVNAME);}return 0;
}static void __exit chrdevbase_exit(void){printk("chrdevbase_exit\r\n");
}// 核心修正点:添加以下声明
MODULE_LICENSE("GPL");          // 必须声明许可证(例如GPL)
MODULE_AUTHOR("Narnat");      // 可选:作者信息
MODULE_DESCRIPTION("chrdevbase"); // 可选:模块描述// 模块入口与出口
module_init(chrdevbase_init);
module_exit(chrdevbase_exit);

app代码:

#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char* argv[]){int ret = 0;int fd;char readbuf[10], writebuf[50];static char userdata[] = {"helloa"};if(argc != 3){printf("ERROR USAGE!\r\n");return -1;}char* filename;filename = argv[1];fd = open(filename, O_RDWR);if(fd < 0){printf("cant open file %s\r\n", filename);return -1;}if(atoi(argv[2]) == 1){ // 读ret =  read(fd, readbuf, sizeof(readbuf));if(ret < 0){printf("read file %s failed\r\n", filename);return -1;}else{printf("RERAD DATA: %s\r\n", readbuf);}}if(atoi(argv[2]) == 2){ // 读memcpy(writebuf, userdata, sizeof(userdata));ret = write(fd, writebuf, sizeof(userdata));if(ret < 0){printf("write file %s failed!\r\n", filename);}}close(fd);return 0;
}

2.实验现象:

在这里插入图片描述

3.总结分析:

用户层在调用open函数打开设备节点后,应用层上的write和read函数调用的是我们自己实现的驱动函数,同理在linux操作系统上调用write和read函数去操作txt文件的时候调用的是系统实现的函数

需要注意的是:

应用层没办法直接读取或写入数据到内核里,所以要借助接口函数copy_to_user、copy_from_user函数去做

app层往内核写数据要注意安全严谨,容易发生缓冲区溢出

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词