Chinaunix首页 | 论坛 | 博客
  • 博客访问: 95640
  • 博文数量: 16
  • 博客积分: 359
  • 博客等级: 一等列兵
  • 技术积分: 279
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-24 22:08
文章分类
文章存档

2014年(3)

2012年(13)

我的朋友

分类: LINUX

2012-03-25 10:05:38

2012年3月25日  Sunday
 
1、内核版本号2.6.33.20
 
2、字符设备驱动创建实例
 
3、驱动模块源文件chr_register.c

点击(此处)折叠或打开

  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/kernel.h>
  4. #include <linux/fs.h>
  5. #include <linux/errno.h>
  6. #include <linux/types.h>
  7. #include <linux/fcntl.h>

  8. #define CALL_DEV_NAME "calldev"
  9. #define CALL_DEV_MAJOR 240

  10. int call_open(struct inode *inode ,struct file *filp)
  11. {
  12.     int num=MINOR(inode->i_rdev);
  13.     
  14.     printk("call open->minor : %d\n",num);
  15.     
  16.     return 0;
  17. }

  18. loff_t call_llseek(struct file *filp,loff_t off,int whence)
  19. {
  20.     printk("call llseek->off : %08X, whence : %08X\n",off,whence);
  21.     return 0x23;
  22. }

  23. ssize_t call_read(struct file *filp,char *buf,size_t count,loff_t *f_pos)
  24. {
  25.     printk("call read->buf : %08X,count : %08X\n",buf,count);
  26.     return 0x33;
  27. }

  28. ssize_t call_write(struct file *filp,const char *buf,size_t count)
  29. {
  30.     printk("call write->buf : %08X,count : %08X\n",buf ,count);
  31.     return 0x43;
  32. }

  33. int call_ioctl(struct inode *inode,struct file *filp,
  34.         unsigned int cmd,unsigned long arg)
  35. {
  36.     printk("call ioctl->cmd : %08X,arg : %08X\n",cmd,arg);
  37.     return 0x53;
  38. }

  39. int call_release(struct inode *inode,struct file *filp)
  40. {
  41.     printk("call release\n");
  42.     return 0;
  43. }

  44. struct file_operations call_fops={
  45.     .owner = THIS_MODULE,
  46.     .llseek = call_llseek,
  47.     .read = call_read,
  48.     .write = call_write,
  49.     .ioctl = call_ioctl,
  50.     .open = call_open,
  51.     .release = call_release,
  52. };

  53. int call_init(void)
  54. {
  55.     int result;
  56.     printk("call call_init\n");
  57.     result=register_chrdev(CALL_DEV_MAJOR,CALL_DEV_NAME,&call_fops);
  58.     if(result<0)return result;
  59.     return 0;
  60. }

  61. void call_exit(void)
  62. {
  63.     printk("call call_exit\n");
  64.     unregister_chrdev(CALL_DEV_MAJOR,CALL_DEV_NAME);
  65. }

  66. module_init(call_init);
  67. module_exit(call_exit);

  68. MODULE_LICENSE("Dual BSD/GPL");

4、Makefile

点击(此处)折叠或打开

  1. obj-m += chr_register.o

  2. CURRENT_PATH := $(shell pwd)

  3. LINUX_KERNEL := $(shell uname -r)

  4. LINUX_KERNEL_PATH := /usr/src/linux-$(LINUX_KERNEL)

  5. all:
  6.     make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
  7. clean:
  8.     #make -C $(LINUX_KERNEL_PAHT) M=$(CURRENT_PATH) clean
  9.     rm *.mod.*
  10.     rm *.order
  11.     rm *.o
  12.     rm *.symvers

5、应用程序源文件call_dev.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <sys/ioctl.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>

  7. #define DEVICE_FILENAME "/dev/calldev"

  8. int main()
  9. {
  10.     int dev;
  11.     char buff[128];
  12.     int ret;
  13.     
  14.     printf("1) device file open\n");
  15.     
  16.     dev=open(DEVICE_FILENAME,O_RDWR |O_NDELAY);
  17.     if(dev>=0){
  18.     
  19.         printf("2)seek function call\n");
  20.         ret=lseek(dev,0x20,SEEK_SET);
  21.         printf("ret=%08X\n",ret);
  22.         
  23.         printf("3)read function call\n");
  24.         ret=read(dev,0x30,0x31);
  25.         printf("ret=%08X\n",ret);
  26.         
  27.         printf("4)write function call\n");
  28.         ret=write(dev,0x40,0x41);
  29.         printf("ret=%08X\n",ret);
  30.         
  31.         printf("5)ioctl function call\n");
  32.         ret=ioctl(dev,0x51,0x52);
  33.         printf("ret=%08X\n",ret);
  34.         
  35.         printf("5)device file close\n");
  36.         ret=close(dev);
  37.         printf("ret=%08X\n",ret);
  38.         
  39.     }
  40.     return 0;
  41. }

6、执行方法及执行结果

点击(此处)折叠或打开

  1. ~/chr_register# mknod /dev/calldev c 240 0 //创建设备文件
  2. ~/chr_register# ls /dev |grep calldev //查看设备文件是否创建成功
  3. calldev
  4. ~/chr_register# make //编译驱动模块
  5. ~/chr_register# insmod chr_register.ko //插入驱动模块
  6. ~/chr_register# lsmod |grep chr_register //查看驱动模块是否插入成功
  7. chr_register 1571 0
  8. ~/chr_register# ./call_app //运行app及结果
  9. 1) device file open
  10. 2)seek function call
  11. ret=00000023
  12. 3)read function call
  13. ret=00000033
  14. 4)write function call
  15. ret=00000043
  16. 5)ioctl function call
  17. ret=00000053
  18. 5)device file close
  19. ret=00000000
  20. ~/chr_register# dmesg //驱动模块内核输出信息
  21. [ 209.833318] call call_init
  22. [ 245.532945] call open->minor : 0
  23. [ 245.532999] call llseek->off : 00000020, whence : 00000000
  24. [ 245.533320] call read->buf : 00000030,count : 00000031
  25. [ 245.533369] call write->buf : 00000040,count : 00000041
  26. [ 245.533440] call ioctl->cmd : 00000051,arg : 00000052
  27. [ 245.533493] call release
  28. [ 280.903004] call call_exit
  29. [ 433.754550] call call_init
  30. [ 468.565086] call open->minor : 0
  31. [ 468.565319] call llseek->off : 00000020, whence : 00000000
  32. [ 468.565423] call read->buf : 00000030,count : 00000031
  33. [ 468.565473] call write->buf : 00000040,count : 00000041
  34. [ 468.565525] call ioctl->cmd : 00000051,arg : 00000052
  35. [ 468.565567] call release

7、移除模块及设备文件

  1. ~/chr_register# rm /dev/calldev //删除设备文件
  2. ~/chr_register# rmmod chr_register.ko //移除驱动模块

阅读(1127) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~