第一个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

原文地址:https://www.cnblogs.com/hello3399/p/5543625.html