当前位置:   article > 正文

Android内核开发 Linux C编程调用内核模块设备驱动

应用程序调用内核模块的方法

本文出处: http://blog.csdn.net/leytton/article/details/52738901

本文目的为Linux系统环境下:1、编写内核模块程序并编译 2、加载内核模块 3、编写C程序调用内核模块

功能为向内核模块虚拟设备写如字符串,再从内核模块虚拟设备读出字符串长度。

1、word_count.c文件

  1. #include<linux/module.h>
  2. #include<linux/init.h>
  3. #include<linux/kernel.h>
  4. #include<linux/fs.h>
  5. #include<linux/miscdevice.h>
  6. #include<asm/uaccess.h>
  7. //设备文件名
  8. #define DEVICE_NAME "word_count"
  9. //保存读写字符串
  10. static unsigned char mem[1000];
  11. //读写字符串中字符数量,ssize_t有符号int,size_t无符号int
  12. static ssize_t char_count=0;
  13. // 从设备文件读取数据时调用该函数
  14. // file:指向设备文件、buf:保存可读取的数据 count:可读取的字节数 ppos:读取数据的偏移量
  15. static ssize_t word_count_read(struct file *file,char __user *buf,size_t read_count,loff_t *ppos)
  16. {
  17. read_count = char_count;
  18. //printk("read:debug:%d\n",(int)char_count);
  19. // 将内核空间的数据复制到用户空间,buf中的数据就是从设备文件中读出的数据
  20. //if(copy_to_user(buf, (void*)mem,read_count)){
  21. if(copy_to_user(buf, &char_count,read_count)){//注意与之前不一样,这次返回字符长度
  22. return -EINVAL;
  23. }
  24. printk("read:read_count:%d\n",(int)read_count);
  25. char_count=0;
  26. return read_count;
  27. }
  28. // 向设备文件写入数据时调用该函数
  29. // file:指向设备文件、buf:保存写入的数据 count:写入数据的字节数 ppos:写入数据的偏移量
  30. static ssize_t word_count_write(struct file *file,const char __user *buf,size_t write_count,loff_t *ppos)
  31. {
  32. char_count=write_count;
  33. // 将用户空间的数据复制到内核空间,mem中的数据就是向设备文件写入的数据
  34. if(copy_from_user((void*)mem,buf,write_count)){
  35. return -EINVAL;
  36. }
  37. mem[write_count]='\0';
  38. printk("write:write_count:%d\n",(int)char_count);
  39. return char_count;
  40. }
  41. static struct file_operations dev_fops=
  42. {.owner=THIS_MODULE, .read=word_count_read, .write=word_count_write};
  43. static struct miscdevice misc=
  44. {.minor=MISC_DYNAMIC_MINOR, .name=DEVICE_NAME, .fops=&dev_fops};
  45. //Linux驱动装载函数
  46. static int __init word_count_init(void)
  47. {
  48. int ret;
  49. //注册设备文件
  50. ret=misc_register(&misc);
  51. printk("word_count init success!");
  52. return ret;
  53. }
  54. //Linux驱动卸载函数
  55. static void __exit word_count_exit(void)
  56. {
  57. // 注销(移除)设备文件
  58. misc_deregister(&misc);
  59. printk("word_count exit success!");
  60. }

2、Makefile文件

  1. TARGET=word_count
  2. KDIR=/usr/src/kernels/3.10.0-327.el7.x86_64 # centos
  3. PWD=$(shell pwd)
  4. obj-m:=$(TARGET).o
  5. default:
  6. make -C $(KDIR) M=$(PWD) modules
  7. clean:
  8. rm -f *.o *.mod.o *.mod.c *.symvers *.order

3、word_count_test.c文件
  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. int main( int argc, char *argv[] )
  7. {
  8. /* 打开设备文件(/dev/word_count)的句柄 */
  9. int devret;
  10. int word_count=0;
  11. int write_count=0;
  12. /* 打开设备文件 */
  13. devret = open( "/dev/word_count", O_RDWR );
  14. /* 如果open函数返回-1,表示打开设备文件失败 */
  15. if ( devret == -1 )
  16. {
  17. printf( "Cann't open file \n" );
  18. return(0);
  19. }
  20. /*
  21. * 如果word_count_test后面跟有命令行参数,程序会将第1个参数值当作待统计的字符串
  22. * 如果没有命令行参数,则只读取设备文件中的值
  23. */
  24. if ( argc > 1 )
  25. {
  26. /* 向设备文件写入待统计的字符串 */
  27. write_count=write( devret, argv[1], strlen( argv[1] ) );
  28. /* 输出待统计的字符串 */
  29. printf( "write string:%s,count:%d\n", argv[1],write_count );
  30. }
  31. // 读取设备文件中的单词数
  32. read(devret, &word_count, sizeof(word_count));
  33. // 输出统计出的单词数
  34. printf("word count:%d\n", word_count);
  35. /* 关闭设备文件 */
  36. close( devret );
  37. return(0);
  38. }
  39. //注册装载函数
  40. module_init(word_count_init);
  41. //注册卸载函数
  42. module_exit(word_count_exit);
  43. MODULE_AUTHOR("Leytton");
  44. MODULE_DESCRIPTION("A simple Word Count Driver");
  45. MODULE_ALIAS("a simplest module");
  46. MODULE_LICENSE("MIT");

4、编译内核模块

  1. [hadoop@localhost drivers01]$ make
  2. make -C /usr/src/kernels/3.10.0-327.el7.x86_64 M=/mnt/workbench/workspace/drivers01 modules
  3. make[1]: 进入目录“/usr/src/kernels/3.10.0-327.el7.x86_64”
  4. CC [M] /mnt/workbench/workspace/drivers01/word_count.o
  5. Building modules, stage 2.
  6. MODPOST 1 modules
  7. CC /mnt/workbench/workspace/drivers01/word_count.mod.o
  8. LD [M] /mnt/workbench/workspace/drivers01/word_count.ko
  9. make[1]: 离开目录“/usr/src/kernels/3.10.0-327.el7.x86_64”
  10. [hadoop@localhost drivers01]$

5、加载内核模块

  1. [hadoop@localhost drivers01]$ sudo insmod word_count.ko
  2. [sudo] password for hadoop:
  3. [hadoop@localhost drivers01]$

6、编译word_count_test.c文件

gcc word_count_test.c -o word_count_test

7、执行word_count_test

  1. [hadoop@localhost drivers01]$ sudo ./word_count_test hello12345
  2. write string:hello12345,count:10
  3. word count:10

注意要用root权限执行,否则会返回以下错误

[hadoop@localhost drivers01]$ ./word_count_test hello12345
Cann't open file 

8、查看内核模块日志

[hadoop@localhost drivers01]$sudo dmesg -c
[15074.261371] write:write_count:10
[15074.261415] read:read_count:10
9、参考文章

《开发可统计单词个数的Android驱动程序(3)》http://www.cnblogs.com/nokiaguy/archive/2013/03/11/2954618.html 

《在Android模拟器和Ubuntu上测试Linux驱动》 http://www.cnblogs.com/nokiaguy/archive/2013/03/14/2960408.html

《 Android深度探索(卷1):HAL与驱动开发》http://blog.csdn.net/nokiaguy/article/details/8540127

《Android驱动与HAL开发实战视频课程》http://edu.51cto.com/course/course_id-2323.html

转载于:https://www.cnblogs.com/leytton/p/8253294.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/327208
推荐阅读
相关标签
  

闽ICP备14008679号