linux驱动学习加强版-3 (驱动代码测试,以及代码完善)
创始人
2025-05-31 20:00:57

文章目录

  • 一、用户测试代码
  • 二、驱动功能完善。
  • 三、open函数的特异性
  • 四、代码中的注意事项

一、用户测试代码

#include 
#include 
#include 
#include 
#include 
#include int main(int argc,char **argv)
{   if(argc <2){printf("Usage:%s -w \n",argv[0]);printf("Usage:%s -r \n",argv[0]);return -1;}int fd;char buf[1024];fd = open("/dev/filectl",O_RDWR);if(fd < 0){printf("can not open /dev/filectl\n");return -1;}if(strcmp(argv[1],"-w")==0 && argc==3){write(fd, argv[2], strlen(argv[2]));}else{read(fd,buf,1024);buf[1023] = '\n';printf("APP get data %s\n",buf);}close(fd);return  0;
}

这样一个简单的用户demo就写完了,然后让我们来试试看结果吧;
使用 gcc -o file_ctl file_test.c 将测试的demo编译为一个可执行文件。
在这里插入图片描述
执行完后是乱码,我们看下log呢

在这里插入图片描述
发现Log是调用了的,为啥呢 。
因为我们驱动之提供了接口,但没有提供功能。
在这里插入图片描述

我们驱动没有提供功能,你们怎么使用呢。哈哈!所以接下来我们需要的是完善驱动功能

二、驱动功能完善。

这个demo的功能就是我调用对应的函数,将我要写的文件传递到底层,然后再把数据读取出来,返回给上层。
这个时候我们就需要内核的标准的函数

copy_from_user  // 从用户空间拷贝文件到驱动
copy_to_user // 从驱动拷贝文件到用户层
#include 
#include 
#include 
#include 
#include 
#include 
#include static int major = 0; //确定主设备号,0默认系统分配
static struct class *filectl_class;
static char kbuffer[1024]; //内核空间的bufferssize_t filectl_read(struct file *file, char __user *buf, size_t size, loff_t *pops)
{int ret;printk("[%s %d]\n", __FUNCTION__, __LINE__);ret = copy_to_user(buf, kbuffer, size);if(ret < 0) {printk("[%s %d]copy_to_user error \n ",__FUNCTION__, __LINE__ );}return size;
}ssize_t filectl_write(struct file *file,const char __user *buf, size_t size, loff_t *pops)
{int ret;printk("[%s %d]\n", __FUNCTION__, __LINE__);ret = copy_from_user(kbuffer, buf, size);if(ret < 0) {printk("[%s %d]copy_from_user error \n ",__FUNCTION__, __LINE__ );}return size;
}int filectl_open(struct inode *inode, struct file *file)
{printk("[%s %d]\n", __FUNCTION__, __LINE__);return 0;
}int filectl_close(struct inode *inode, struct file *file)
{printk("[%s %d]\n", __FUNCTION__, __LINE__);return 0;
}// 定义自己的驱动的 file_operations
static struct file_operations filectl_ops = {.owner	 = THIS_MODULE,.read    = filectl_read,.write   = filectl_write,.open    = filectl_open,.release = filectl_close, // 好像没有close这个函数
};static int __init filectl_init(void)
{// 在初始化的时候进行驱动注册,设备号major = register_chrdev(0,"filectl",&filectl_ops);if(major < 0) {printk("[%s %d] filectl error\n", __FUNCTION__, __LINE__); // 注册失败return -1;}filectl_class = class_create(THIS_MODULE, "filectl"); // class_create 动态创建dev的类// IS_ERR 查看指针是否有错误if(IS_ERR(filectl_class)) {printk("[%s %d] class_create error\n", __FUNCTION__, __LINE__);unregister_chrdev(major,"filectl");return -1;}// 创建字符设备device_create(filectl_class, NULL, MKDEV(major, 0),NULL, "filectl");printk("[%s %d] filectl driver create success\n", __FUNCTION__, __LINE__);return 0;
}static void __exit filectl_exit(void) {device_destroy(filectl_class, MKDEV(major, 0));class_destroy(filectl_class);// 注销字符设备unregister_chrdev(major,"filectl");printk("[%s %d]goodbye filectl driver\n",  __FUNCTION__, __LINE__);
}module_init(filectl_init);
module_exit(filectl_exit);
MODULE_LICENSE		("GPL");
MODULE_AUTHOR		("cong.luo");
MODULE_DESCRIPTION	("First file contrl module");

再来测试一把呢:
在这里插入图片描述
在这里插入图片描述

这样就OK了哇。

三、open函数的特异性

下面我们修改下代码:
首先是驱动文件,我们去掉read、write、open

#include 
#include 
#include 
#include 
#include 
#include 
#include static int major = 0; //确定主设备号,0默认系统分配
static struct class *filectl_class;
static char kbuffer[1024]; //内核空间的buffer// ssize_t filectl_read(struct file *file, char __user *buf, size_t size, loff_t *pops)
// {
//     int ret;
// 	printk("[%s %d]\n", __FUNCTION__, __LINE__);
//     ret = copy_to_user(buf, kbuffer, size);
//     if(ret < 0) {
//         printk("[%s %d]copy_to_user error \n ",__FUNCTION__, __LINE__ );
//     }
//     return size;
// }// ssize_t filectl_write(struct file *file,const char __user *buf, size_t size, loff_t *pops)
// {
//     int ret;
// 	printk("[%s %d]\n", __FUNCTION__, __LINE__);
//     ret = copy_from_user(kbuffer, buf, size);
//     if(ret < 0) {
//         printk("[%s %d]copy_from_user error \n ",__FUNCTION__, __LINE__ );
//     }
//     return size;
// }// int filectl_open(struct inode *inode, struct file *file)
// {
// 	printk("[%s %d]\n", __FUNCTION__, __LINE__);
//     return 0;
// }int filectl_close(struct inode *inode, struct file *file)
{printk("[%s %d]\n", __FUNCTION__, __LINE__);return 0;
}// 定义自己的驱动的 file_operations
static struct file_operations filectl_ops = {.owner	 = THIS_MODULE,// .read    = filectl_read,// .write   = filectl_write,//.open    = filectl_open,.release = filectl_close, // 好像没有close这个函数
};static int __init filectl_init(void)
{// 在初始化的时候进行驱动注册,设备号major = register_chrdev(0,"filectl",&filectl_ops);if(major < 0) {printk("[%s %d] filectl error\n", __FUNCTION__, __LINE__); // 注册失败return -1;}filectl_class = class_create(THIS_MODULE, "filectl"); // class_create 动态创建dev的类// IS_ERR 查看指针是否有错误if(IS_ERR(filectl_class)) {printk("[%s %d] class_create error\n", __FUNCTION__, __LINE__);unregister_chrdev(major,"filectl");return -1;}// 创建字符设备device_create(filectl_class, NULL, MKDEV(major, 0),NULL, "filectl");printk("[%s %d] filectl driver create success\n", __FUNCTION__, __LINE__);return 0;
}static void __exit filectl_exit(void) {device_destroy(filectl_class, MKDEV(major, 0));class_destroy(filectl_class);// 注销字符设备unregister_chrdev(major,"filectl");printk("[%s %d]goodbye filectl driver\n",  __FUNCTION__, __LINE__);
}module_init(filectl_init);
module_exit(filectl_exit);
MODULE_LICENSE		("GPL");
MODULE_AUTHOR		("cong.luo");
MODULE_DESCRIPTION	("First file contrl module");

在app代码中添加一些打印:

#include 
#include 
#include 
#include 
#include 
#include int main(int argc,char **argv)
{   if(argc <2){printf("Usage:%s -w \n",argv[0]);printf("Usage:%s -r \n",argv[0]);return -1;}int fd;char buf[1024];fd = open("/dev/filectl",O_RDWR);if(fd < 0){printf("can not open /dev/filectl\n");return -1;}printf("open /dev/filectl success \n");if(strcmp(argv[1],"-w")==0 && argc==3){int err = write(fd, argv[2], strlen(argv[2]));if (err < 0 ) {printf("write /dev/filectl error \n");return -1;}printf("write /dev/filectl success \n");}else{int err = read(fd,buf,1024);if (err < 0 ) {printf("read /dev/filectl error \n");return -1;}printf("read /dev/filectl success \n");buf[1023] = '\n';printf("APP get data %s\n",buf);}close(fd);return  0;
}

在这里插入图片描述没有read和write函数,我们无法读写。
但是我们可以进行open,这说明了open函数是一个比较特殊的函数,或许硬件默认就是可以进行open的,是为了方便一些初始化吧。大家记住就好。

四、代码中的注意事项

copy_to_user 和 copy_from_user传递的参数位置是不一样的哟

ret = copy_to_user(buf, kbuffer, size);
ret = copy_from_user(kbuffer, buf, size);

有些小伙伴可能没有注意到这点。

相关内容

热门资讯

最新!2025新势力5月销量出... 5月新势力表现如何?2025年5月的销售周期刚刚过去,不少造车新势力厂商的销量数据,已经新鲜出炉。数...
两家A股公司,收终止上市决定 又有两家A股上市公司收到股票终止上市决定,6月10日进入退市整理期。 上述自律监管决定书指出,因2...
重磅,事关教育强国,主力提前埋... 数据是个宝数据宝投资少烦恼这些产业的景气度处于上升期。《求是》杂志发表文章《加快建设教育强国》6月1...
阳光诺和“二刷”收购 80后富... 《投资者网》蔡俊时隔2年后,阳光诺和(688621.SH,下称“公司”)再拟收购同一个资产。实际上,...
买车,不安全了? 买车,不安全... 在新能源汽车市场竞争空前激烈的当下,车企、经销商习惯于采取更加激进的营销、市场策略,尤其在行业加速“...
欧佩克+同意7月再增产41.1... 为了增产惩罚超产国并争夺市场份额,欧佩克+连续第三个月大幅增产,美国页岩油生产商或首当其冲,美油一度...
经济学泰斗菲舍尔逝世:培育伯南... 当地时间6月1日,以色列央行发布声明称,世界著名经济学家、以色列央行前行长及美联储前副主席菲舍尔(S...
更名!“天府证券”来了 天府证... 【导读】宏信证券更名为天府证券中国基金报记者 吴君这家券商,历史上第二次更名。5月末,工商信息显示,...
两家A股公司,收终止上市决定 ... 又有两家A股上市公司收到股票终止上市决定,6月10日进入退市整理期。*ST鹏博(600804)公告称...
瑞幸降价迈入“6块9”时代?瑞... 说起最近几年的咖啡茶饮市场,相信每个人都不会陌生,各家咖啡茶饮企业的各种降价消息是此起彼伏,就在最近...
主次节奏:6.1黄金 - 每周... 本文每周初更新发布梳理各级别走势分析和预期主次节奏:做有品质的三方服务黄金月线图(超长线) 月线图...
超400亿资金狂涌!这类ETF... 债券ETF市场持续扩容。今年以来,债券市场表现震荡,债券类基金回报远不及预期,但这并未妨碍债券型ET...
坚定信心 行稳致远(记者手记) 侯琳良 最近一段时间,海尔集团上世纪90年代投资制作的《海尔兄弟》动画片,在多个视频平台上线高清重制...
世纪大辩论2——哈耶克与凯恩斯... 本来节后决定启动一个项目,但家里临时有事,需要陪家人去一趟北京,节后拉群的事,因此要推迟一周左右(具...
4月广州消费品市场表现强劲 1-4月,随着消费品以旧换新等促消费政策持续发力和各类会展活动陆续开展,政策相关消费快速增长,升级类...
金价,又跌了! 人民财讯5月31日电,5月30日,COMEX黄金期货收跌0.92%,报3313.1美元/盎司。 从高...
10万吨改性项目!巴斯夫、金发... 【DT新材料】获悉,6月3日,沪市主板新股海阳科技将启动申购,上市在即! 资料显示,海阳科技前身为南...
湾财周报|大事记 比亚迪驳斥“... 一周大事记(5月26日-6月1日) 头条 比亚迪驳斥! 长城“车圈恒大论”是行业警示还是危言耸听?...
通源石油跌1.96%,成交额1... 5月30日,通源石油跌1.96%,成交额1.03亿元,换手率4.40%,总市值23.54亿元。 异动...
中国邮储银行浙江分行2025校... 点这里 ↑ 老满说高考 作者 l 老满 生涯规划师l 升学顾问l 拆书家 这是 老满说高考公众号 的...
公募基金规模首次突破33万亿元... 每经记者:肖芮冬 每经编辑:叶峰 天赐良基日报第654期 一、今日基金新闻速览 1、华润元大基金贾...
湾财周报 大事记 比亚迪驳斥“... 一周大事记(5月26日-6月1日)头条比亚迪驳斥!长城“车圈恒大论”是行业警示还是危言耸听?近日,关...
EL表达式JSTL标签库 EL表达式     EL:Expression Language 表达式语言     ...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
工信部、中汽协紧急发声!汽车“... 文/刘育英新一轮汽车价格战再起。近日,工信部、中汽协纷纷发声表示反对。工业和信息化部表示,将加大对汽...
3 ROS1通讯编程提高(1) 3 ROS1通讯编程提高3.1 使用VS Code编译ROS13.1.1 VS Code的安装和配置...
募资39亿,全亏光了,账上不到... 关于天然气,用户的感觉是价格一直在上涨,但很奇怪,不管怎么涨,天然气企业仍然亏,还亏得一塌糊涂。这是...
资阳房产评估公司 这是(tel-15828298733)整理的信息,希望能帮助到大家 在当今社会,随着经济的发展和城...
华桥汇利(中国)投资基金管理有... 今年第一季度,美国企业利润出现大幅下降,且面临着来自关税上升的持续压力,这一局面可能会在今年进一步加...
ESG 报告合规与鉴证:全球政... 在当下全球经济格局里,ESG(环境、社会和公司治理)已然成为衡量企业可持续发展能力的关键指标。随着全...