第一个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\n");
return 0;
}
//退出Linux驱动
static void word_count_exit(void)
{
printk("word_count_exit_success\n");
}
//注册初始化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 == '\0')
return 0;
//第一个字符是空格,从零开始计数
if (is_spacewhite(*buf) == TRUE)
n --;
//扫描字符串中的每一个字符
for (; (c = *(buf + i)) != '\0'; 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] = '\0';
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