八、 指定回调函数
本节讲的内容十分关键。不管Linux驱动程序的功能多么复杂还是多么“酷”,都必须允许用户空间的应用程序与内核空间的驱动程序进行交互才有意义。而最 常用的交互方式就是读写设备文件。通过file_operations.read和file_operations.write成员变量可以分别指定读写 设备文件要调用的回调函数指针。
在本节将为word_count.c添加两个函数:word_count_read和word_count_write。这两个函数分别处理从设备文件读 数据和向设备文件写数据的动作。本节的例子先不考虑word_count要实现的统计单词数的功能,先用word_count_read和 word_count_write函数做一个读写设备文件数据的实验,以便让读者了解如何与设备文件交互数据。本节编写的word_count.c文件是 一个分支,读者可在word_count/read_write目录找到word_count.c文件。可以用该文件覆盖word_count目录下的同 名文件测试本节的例子。
本例的功能是向设备文件/dev/wordcount写入数据后,都可以从/dev/wordcount设备文件中读出这些数据(只能读取一次)。下面先看看本例的完整的代码。
#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #define DEVICE_NAME "wordcount" // 定义设备文件名 static unsigned char mem[10000]; // 保存向设备文件写入的数据 static char read_flag = 'y'; // y:已从设备文件读取数据 n:未从设备文件读取数据 static int written_count = 0; // 向设备文件写入数据的字节数 // 从设备文件读取数据时调用该函数 // file:指向设备文件、buf:保存可读取的数据 count:可读取的字节数 ppos:读取数据的偏移量 static ssize_t word_count_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { // 如果还没有读取设备文件中的数据,可以进行读取 if(read_flag == 'n') { // 将内核空间的数据复制到用户空间,buf中的数据就是从设备文件中读出的数据 copy_to_user(buf, (void*) mem, written_count); // 向日志输出已读取的字节数 printk("read count:%d", (int) written_count); // 设置数据已读状态 read_flag = 'y'; return written_count; } // 已经从设备文件读取数据,不能再次读取数据 else { return 0; } } // 向设备文件写入数据时调用该函数 // file:指向设备文件、buf:保存写入的数据 count:写入数据的字节数 ppos:写入数据的偏移量 static ssize_t word_count_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { // 将用户空间的数据复制到内核空间,mem中的数据就是向设备文件写入的数据 copy_from_user(mem, buf, count); // 设置数据的未读状态 read_flag = 'n'; // 保存写入数据的字节数 written_count = count; // 向日志输出已写入的字节数 printk("written count:%d", (int)count); return count; } // 描述与设备文件触发的事件对应的回调函数指针 // 需要设置read和write成员变量,系统才能调用处理读写设备文件动作的函数 static struct file_operations dev_fops = { .owner = THIS_MODULE, .read = word_count_read, .write = word_count_write }; // 描述设备文件的信息 static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops }; // 初始化Linux驱动 static int word_count_init(void) { int ret; // 建立设备文件 ret = misc_register(&misc); // 输出日志信息 printk("word_count_init_success\n"); return ret; } // 卸载Linux驱动 static void word_count_exit(void) { // 删除设备文件 misc_deregister(&misc); // 输出日志信息 printk("word_init_exit_success\n"); } // 注册初始化Linux驱动的函数 module_init( word_count_init); // 注册卸载Linux驱动的函数 module_exit( word_count_exit); MODULE_AUTHOR("lining"); MODULE_DESCRIPTION("statistics of word count."); MODULE_ALIAS("word count module."); MODULE_LICENSE("GPL");
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索文件
, 数据
, 函数
, static
, 统计单词出现个数
, count
, count()
, 设备
, word读取
, 读取word数据
, 读取Word
, count(*)
, read函数
单词数
android驱动开发、android底层驱动开发、android驱动开发书籍、android usb驱动开发、android音频驱动开发,以便于您获取更多的相关知识。