zoukankan      html  css  js  c++  java
  • 第一个Linux驱动程序:统计单词个数

    编写linux驱动程序步骤:

    1、建立linux驱动骨架(装载和卸载linux驱动)

      #include <linux/module.h>

      #include <linux/init.h>

      #include <linux/init.h>

      #include <linux/kernel.h>

      #include <linux/fs.h>

      #include <linux/miscdevice.h>

      #include <asm/uaccess.h>

      //初始化Linux驱动

      static int word_count_init(void)

      {

         printk("word_count_init_success ");

         return 0; 

      }

      //退出Linux驱动

      static void word_count_exit(void)

      {

         printk("word_count_exit_success ");

      }

      //注册初始化Linux驱动的函数

      module_init(word_count_init);

      //注册退出Linux驱动的函数

      module_exit(word_count_exit);

    2、指定与驱动相关的信息

      MODULE_AUTHOR("lining");  //模块作者

      MODULE_DESCRIPTION("statistics of word count.");  //模块描述

      MODULE_ALIAS("word count module.");  //模块别名

      MODULE_LICENSE("GPL");  //开源协议

    3、注册和注销设备文件

      修改word_count.c文件

      #define DEVICE_NAME "wordcount"  //定义设备文件名

      static struct file_operations dev_fops = { .owner = ThIS_MODULE};  //描述与设备文件触发的事件对应的回调函数指针

      static struct miscdevice misc =     //描述设备文件的信息

      {

        .minor = MISC_DYNAMIC_MINOR,  //次设备号,动态生成次设备号(杂项设备主设备号为10)

        .name = DEVICE_NAME,  //设备文件名称

        .fops = &dev_fops  //file_operations结构体变量指针

      };

      static int word_count_init(void)

      {

        int ret;

        ret = misc_register(&misc);  //建立设备文件

        return ret;

      }

      staitc void word_exit(void)

      {

        misc_deregister(&misc);  //注销(移除)设备文件

      }

    4、指定回调函数

      static unsigned char mem[1000];  //保存向设备文件写入的数据

      static int word_count = 0;  //单词数

      #define TRUE -1

      #define FALSE 0

      //判断指定字符是否为空格(包括空格符、制表符、回车符、换行符)

      static char is_spacewhite(char c)

      {

        if (c == ' ' || c == 9 || c == 13 || c == 10)

          return TRUE;

        else

          return FALSE;

      }

      //统计单词数

      static int get_word_count(const char *buf)

      {

        int n = 1;

        int i = 0;

        char c = ' ';

        char flag = 0;  //处理多个空格分隔的情况,0: 正常,1:已遇到一个空格

        if (*buf == '')

          return 0;

        //第一个字符是空格,从零开始计数

        if (is_spacewhite(*buf) == TRUE)

          n --;

        //扫描字符串中的每一个字符

        for (; (c = *(buf + i)) != ''; i++)

        {

          //只有一个空格分隔单词的情况

          if (flag == 1 && is_spacewhite(c) == FALSE)

            frag = 0;

          //由多个空格分隔单词的情况,忽略多余的空格

          else if (flag == 1 && is_spacewhite(c) == TRUE)

            continue;

          //当前字符为空格时单词数加1

          if (is_spacewhite(c) == TRUE)

          {

            n++;

            flag = 1;

          }

        }

        //如果字符串以一个或多个空格结尾,不计数(单词数减1)

        if (is_spacewhite(*(buf + i - 1)) == TRUE)

          n--;

        return n;

      }

      //从设备文件读取数据时调用该函数,file: 指向设备文件 buf:保存可读取的数据 count:可读取的字节数 ppos:读取数据的偏移量

      static ssize_t word_count_read(struct file *file, char _user *buf, size_t count, loff_t *ppos)

      {

        unsigned char temp[4];

        //将单词数(int类型)分解成4个字节存储在buf中

        temp[0] = word_count >> 24;

        temp[1] = word_count >> 16;

        temp[2] = word_count >> 8;

        temp[3] = word_count;

        copy_to_user(buf, (void*) temp, 4);

        printk("read:word count : %d", (int) count);

        return count;

      }

      //向设备文件写入数据时调用该函数

      static ssize_t word_count_write(struct file *file, const char _user *buf, size_t count, loff_t *ppos)

      {

        ssize_t writen = count;

        copy_from_user(mem, buf, count);

        mem[count] = '';

        word_count = get_word_count(mem);

        printk("write : word count : %d", (int) word_count);

        return writen;   

      }

      static struct file_operations dev_fops =

      {

        .owner = THIS_MODULE,

        .read = word_count_read,

        .write = word_count_write

      };

    5、编译驱动

    6、安装和卸载Linux驱动

      安装Linux驱动:# insmod word_count.ko

      卸载Linux驱动:# rmmod word_count

  • 相关阅读:
    [zz]std::vector,std::deque,std::list的区别的使用
    [zz]有关写c++代码的习惯
    [zz]Ubuntu linux 基本操作 双网卡双IP配置
    [zz]ZooKeeper 典型的应用场景
    [zz]Ubuntu配置双网卡
    java配置文件问题
    Struts2知识积累(2)_核心概念:拦截器
    【双旦献礼】PortalBasic Java Web 应用开发框架 v3.0.1 正式发布(源码、示例及文档)
    hibernate入门
    为Eclipse定制你自己的注释模板变量
  • 原文地址:https://www.cnblogs.com/hello3399/p/5543625.html
Copyright © 2011-2022 走看看