Hello,World驱动之旅,用户层简单交互(三)

目录

(一)上篇回顾:上一篇讲到用户层怎么与驱动模块进行交互。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博客

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值