目录
(一)上篇回顾:上一篇讲到用户层怎么与驱动模块进行交互。Hello,World驱动之旅,对外接口(二)-CSDN博客
(二)通过简单程序与驱动交互
读操作,代码如下:
写操作,代码如下:
主函数如下:
(三)编译源码指令:gcc test.c -o test
(四)执行指令:./test
(五)源代码如下
(一)上篇回顾:上一篇讲到用户层怎么与驱动模块进行交互。Hello,World驱动之旅,对外接口(二)-CSDN博客
1.通过insmod加载驱动
2.通过指令echo指令对驱动文件节点进行写操作
3.通过指令cat对驱动文件节点进行读操作
4.驱动底层记录写入次数,并通过cat读操作反馈出来。
(二)通过简单程序与驱动交互
前文已经通过指令echo、cat与驱动模块进行了交互,接下来我们通过简单的C语言程序与驱动程序进行交互。
读操作,代码如下:
int sys_files_read(char *path,char *buf,int len){
int ret;
int fd;
if(NULL == buf){
return -1;
}
//打开文件
fd = open(path, O_RDONLY);
if(fd > 0){
//读文件
ret = read(fd, buf, len);
if(ret<0){
close(fd);
return -2;
}
//关闭文件
close(fd);
return ret;
}else{
return -3;
}
}
open、read、close为linux系统调用,通过指令“man 2 xxxx”可以查看具体系统调用用法,包括头文件、参数、返回值、错误码等。xxx即为open、read、write等,示例指令如下:
写操作,代码如下:
//sys file write operation
int sys_files_write(char *path,char *buf,int len){
int ret;
int fd;
if(NULL == buf){
return -1;
}
//打开文件
fd = open(path, O_WRONLY);
if(fd > 0){
//写文件
ret = write(fd, buf, len);
if(ret<0){
close(fd);
return -2;
}
//关闭文件
close(fd);
return 0;
}else{
return -3;
}
}
主函数如下:
int main(int argc,char **argv){
int ret;
char *buf = (char *)malloc(1024);
if(NULL == buf){
printf("not enought memory\n");
return -1;
}
ret = sys_files_read(TEST_DRIVER_SYSFILE,buf,1024);
if(ret > 0){
printf("%s",buf);
}else{
printf("read file error,error code=%d\n",ret);
}
ret = sys_files_write(TEST_DRIVER_SYSFILE, "1", 1);
if(0 != ret){
printf("write file error,error code=%d\n",ret);
}else{
printf("write %s successful\n",TEST_DRIVER_SYSFILE);
}
free(buf);
return 0;
}
其中驱动节点文件"/sys/class/cdevhelloclass/test"对应宏定义TEST_DRIVER_SYSFILE 即为驱动文件所对应的底层节点文件。main函数中,每次对该文件进行一次读写操作。
(三)编译源码指令:gcc test.c -o test
(四)执行指令:./test
貌似结果与预期不符,从code返回-3可知,程序在open的时候就出错了,具体什么原因导致的出错,我们可以通过errno获取,稍微修改下程序,在return -3之前增加如下代码:
printf("%s\n",strerror(errno));
再编译执行一次,效果如下,提示没有相应目录:
是的、由于我虚拟机重启了,此处未加载驱动模块,执行指令sudo insmod hello.ko,再次执行指令如下:
有变化,没有文件或者目录错误解决了,当前提示没有权限,使用ls命令看看具体该文件本身所具备的权限,执行如下指令ls -l /sys/class/cdevhelloclass/test
果然,当前文件的用户属于root,目前只有root用户可以读写(rw-)、其他用户只能读(r--),接下来解决思路有两个:
第一:通过sudo指令执行test程序,
第二:通过chmod指令修改驱动文件权限sudo chmod 666 /sys/class/cdevhelloclass/test
我们可以看到,该文件的权限由之前的rw-r--r--,修改为rw-rw-rw-,再次通过指令./test执行,不加sudo,效果如下,异常已解决,同时我们也可以看出,每执行一次,我们的count都会增加1。
至此介绍完一个简单的与底层驱动交互的test程序,麻雀虽小五脏俱全。接下来我们看看,如何通过java来与我们的驱动进行交互,可以满足后续的Android开发。
(五)源代码如下
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <errno.h> #define TEST_DRIVER_SYSFILE ("/sys/class/cdevhelloclass/test") int sys_files_read(char *path,char *buf,int len){ int ret; int fd; if(NULL == buf){ return -1; } fd = open(path, O_RDONLY); if(fd > 0){ ret = read(fd, buf, len); if(ret<0){ close(fd); return -2; } close(fd); return ret; }else{ printf("%s\n",strerror(errno)); return -3; } } //sys file write operation int sys_files_write(char *path,char *buf,int len){ int ret; int fd; if(NULL == buf){ return -1; } fd = open(path, O_WRONLY); if(fd > 0){ ret = write(fd, buf, len); if(ret<0){ close(fd); return -2; } close(fd); return 0; }else{ printf("%s\n",strerror(errno)); return -3; } } int main(int argc,char **argv){ int ret; char *buf = (char *)malloc(1024); if(NULL == buf){ printf("not enought memory\n"); return -1; } ret = sys_files_read(TEST_DRIVER_SYSFILE,buf,1024); if(ret > 0){ printf("%s",buf); }else{ printf("read file error,error code=%d\n",ret); } ret = sys_files_write(TEST_DRIVER_SYSFILE, "1", 1); if(0 != ret){ printf("write file error,error code=%d\n",ret); }else{ printf("write %s successful\n",TEST_DRIVER_SYSFILE); } free(buf); return 0; }
Hello,World驱动之旅,初识驱动模块(一)-CSDN博客