• Linux驱动开发一.字符设备框架——3.应用程序


    在前面章节我们完成了驱动框架的编写,但是只能通过命令将驱动的模块挂载然后生成设备节点(/dev/testdev)。下面我们需要写一个应用程序,来对这个文件进行读写等操作。

    打开/关闭文件

    要对文件进行读写操作必须涉及到打开/关闭文件,Linux系统提供了相对应的函数进行文件的打开/关闭。

    open函数

    文件打开要用到open函数。open函数的使用可以通过man命令查询一下使用方法

     帮助信息里给出了要使用open函数时要导入的头部信息,我们使用open函数参数形式为第一个

    int open(const char *pathname, int flags);

    open函数里第一个参数为文件名,第二个标志说明如下

    我们需要对文件进行读写操作,所以就是0_RDWR。 

    close函数

    关闭和打开必然是成对出现的,close函数的用法要简单的多

    参数fd是open函数的返回值。

    打开和关闭的过程如下:

    /**
     * @file app.c
     * @author your name (you@domain.com)
     * @brief 驱动应用程序
     * @version 0.1
     * @date 2022-03-27
     * 
     * @copyright Copyright (c) 2022
     * 
     */
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    int main(int argc,char *argv[])
    {
        char *filename;                 //文件名
        filename = argv[1];             //文件名为命令行后第二个参数(索引值为1)
    
        int f = 0;
        f = open(filename, O_RDWR);     //打开文件
    
        close(f);                       //关闭文件
        return 0;
    }

    因为这个应用程序是跑在arm架构下的,所以不能用gcc编译,要用交叉编译器编译一下,修改权限复制到根文件系统下(为了方便和.ko文件放在一起)。可以file看一下文件的信息

     可以看出来编译出来的是执行文件,ARM架构的,所以在X86架构下是无法使用的,但是在开发板下可以运行。

    $ arm-linux-gnueabihf-gcc app.c -o app
    $ sudo chmod 777 app

    在串口里启动开发板,挂载好模块并生成设备节点,运行程序就可以了

    dev open和dev release就是我们在驱动文件里定义的让内核打印的信息,说明程序没问题。

    文件读写

    文件读写要在打开文件之后,用到的函数为write和read。

    读文件

    读文件函数为read(),用man打印出的帮助信息

     把读写过程添加在应用程序中(要在打开和关闭之间)

    /**
     * @file app.c
     * @author your name (you@domain.com)
     * @brief 驱动应用程序
     * @version 0.1
     * @date 2022-03-27
     * 
     * @copyright Copyright (c) 2022
     * 
     */
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    
    int main(int argc,char *argv[])
    {
        char *filename;                 //文件名
        filename = argv[1];             //文件名为命令行后第二个参数(索引值为1)
    
        int ret = 0;                    //初始化操作返回值
        int f = 0;                      //初始化文件句柄
        char readbuf[100];              //初始化读数据缓存
        char writebuf[100];             //初始化写数据缓存
    
    
        f = open(filename, O_RDWR);     //打开文件
    
        if(f < 0){
            printf("open file %s failed!\r\n", filename);
        }
    
        ret = read(f, readbuf , 50);
        if (ret < 0)
        {
            printf("read err!");
        }
        else{
    
        }
    
        ret = write(f, writebuf, 50);
    
        if(ret <0){
            printf("write err!");
        }
        
        return 0;
    }

    注意这里的printf函数,一定要显性的调用stdio.h这个库文件。不能直接使用。整个过程和打开关闭稍微有些区别,增加了异常处理(打印信息)。一般情况来说操作都返回值如果异常都是负数。所以当操作都返回值小于0就是有异常,打印相关信息就可以了。make以后复制到根目录系统下运行一下

    所有打印出来的信息是通过内核打调用了驱动文件里相关的函数印出来的 。

    可以通过上面的流程看出来,我们在应用程序通过调用了系统调用函数open、read、write和close四个文件操作函数,在对文件进行操作都时候,对应的操作通过驱动里定义的文件操作结构体里关联的函数进行相对应的操作。下一章我们将驱动文件和应用程序优化 一下,来测试一下驱动效果。

  • 相关阅读:
    HBase的Snapshots功能介绍
    Java 向Hbase表插入数据报(org.apache.hadoop.hbase.client.HTablePool$PooledHTable cannot be cast to org.apac)
    独立搭建zookeeper
    zookeeper原理
    Hbase 配置问题(ERROR: org.apache.hadoop.hbase.PleaseHoldException: org.apache.hadoop.hbase.PleaseHoldEx)
    vmware时间不同步的问题
    Hadoop Error:Name node is in safe mode的解决方法
    Hadoop集群的安装与配置(centos 6.5)
    WIN7 数据源配置问题(32位&&64位)
    JS禁用浏览器退格键
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/16062532.html
Copyright © 2020-2023  润新知