热门内容

公众号"MAKE1"

获取行业最新资讯

请扫码添加

专业客服企业微信

创建设备节点--手动方法

简介

创建设备节点--手动方法

Android2.3及Linux2.6.29内核模拟器版本编译与调试

一、手动创建

1.驱动模块

test_driver.c

  1. //#include <linux/devfs_fs_kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/types.h>
  4. #include <linux/uaccess.h>
  5. #include <linux/miscdevice.h>
  6. #include <linux/fs.h>
  7. #include <linux/init.h>
  8. #include <linux/platform_device.h>
  9.  
  10. #define TEST_MAJOR 240
  11.  
  12. //动态设备节点
  13. //struct class *mymodule_class;
  14. //结束
  15. static int test_led_open(struct inode *inode, struct file *file)
  16. {
  17. printk("#########open######n");
  18. return 0;
  19. }
  20.  
  21.  
  22. static int test_led_close(struct inode *inode, struct file *file)
  23. {
  24. printk("#########release######n");
  25. return 0;
  26. }
  27.  
  28.  
  29. static int test_led_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
  30. {
  31. printk("#########read######n");
  32. return count;
  33. }
  34.  
  35. static int test_led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
  36. {
  37. printk("#########write######n");
  38. return count;
  39. }
  40.  
  41.  
  42. static struct file_operations led_fops = {
  43. .owner = THIS_MODULE,
  44. .open = test_led_open,
  45. .release = test_led_close,
  46. .read = test_led_read,
  47. .write = test_led_write,
  48. };
  49.  
  50. static int __init test_drv_init(void)
  51. {
  52. int rc;
  53. printk("test_driver devn");
  54. //注册设备
  55. rc = register_chrdev(TEST_MAJOR,"test_dev",&led_fops);
  56. if (rc <0){
  57. printk ("register %s char dev errorn","led");
  58. goto out_chrdev;
  59. }
  60. //devfs文件系统创建
  61. /*
  62. devfs_mk_cdev( MKDEV(TEST_MAJOR, 0),
  63. S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, "test_dev");
  64. */
  65. //结束
  66. //实现动态创建
  67. //mymodule_class = class_create(THIS_MODULE, "test_dev");//在/sys/class/下创建“test_dev”目录
  68. //device_create(mymodule_class, NULL, MKDEV(TEST_MAJOR, 0), NULL, "tankai_dev"); //在/dev/下创建“tankai_dev”文件
  69. //结束
  70. printk ("ok!n");
  71. return 0;
  72.  
  73.  
  74. out_chrdev:
  75. unregister_chrdev(TEST_MAJOR, "mymodule");
  76. }
  77.  
  78. static void __exit test_drv_exit(void)
  79. { //动态设备节点
  80. //device_destroy(mymodule_class, MKDEV(TEST_MAJOR, 0));
  81. //class_destroy(mymodule_class);
  82. //结束
  83. unregister_chrdev(TEST_MAJOR, "test_dev");
  84. }
  85.  
  86. module_init(test_drv_init);
  87. module_exit(test_drv_exit);
  88.  
  89. MODULE_AUTHOR("tank");
  90. MODULE_LICENSE("GPL");

Makefile

  1. obj-m := test_driver.o
  2. PWD := $(shell pwd)
  3. #KERNELDIR := /usr/src/linux-headers-3.0.0-26-generic/
  4. KERNELDIR := /home/android2.3/android2.3_kernel/
  5. default:
  6. $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  7. # cp -rf mini.ko ../module/
  8. # cp -rf lddbus.ko ../module/
  9. clean:
  10. rm *.mod.c *.o *.ko *.bak modules.* Module.*

2.Android模拟器没有mknod命令,我们实现它

mknod.c

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #define S_IFCHR 0020000
  4.  
  5. int main(int argc,char *argv[])
  6. {
  7. if(argc != 3){
  8. printf("error:Two canshun");
  9. return -1;
  10. }
  11. char *devname = argv[1];
  12. printf("devname is %sn",devname);
  13. int devnum = -1;
  14. sscanf(argv[2],"%d",&devnum);
  15. printf("devnum is %dn",devnum);
  16. if(mknod(devname,S_IFCHR|0666,makedev(devnum,0))!=0)
  17. perror("mknod");
  18. return 0;
  19. }

Android.mk

  1. LOCAL_PATH:= $(call my-dir)
  2. include $(CLEAR_VARS)
  3.  
  4. LOCAL_SRC_FILES:=
  5. mknod.c
  6.  
  7. LOCAL_SHARED_LIBRARIES :=
  8. libutils
  9.  
  10. LOCAL_MODULE:= mknod
  11.  
  12. LOCAL_MODULE_TAGS := optional
  13.  
  14. include $(BUILD_EXECUTABLE)

查看:cat /proc/devices

结果:

  1. Character devices:
  2. 1 mem
  3. 4 /dev/vc/0
  4. 4 tty
  5. 5 /dev/tty
  6. 5 /dev/console
  7. 5 /dev/ptmx
  8. 7 vcs
  9. 10 misc
  10. 13 input
  11. 14 sound
  12. 29 fb
  13. 90 mtd
  14. 116 alsa
  15. 128 ptm
  16. 136 pts
  17. 240 test_dev
  18. 253 ttyS
  19. 254 rtc
  20.  
  21. Block devices:
  22. 1 ramdisk
  23. 259 blkext
  24. 7 loop
  25. 31 mtdblock
  26. 43 nbd
  27. 179 mmc
  28. 254 device-mapper

执行:./mknod /dev/tankai_dev 240

//这里只需要给出主设备号,主设备号相同的设备使用同一驱动程序;只是加入次设备号后可以实现一个驱动,多个设备使用的情况。这个目前我们的驱动中没有实现;因此,次设备号可以随便。

ll /dev/tankai_dev

结果:

  1. crw-rw-rw- root root 240, 0 2013-10-16 09:54 tankai_dev

3.测试用例

testdriver.c

  1. #include <fcntl.h>
  2. #include <stdlib.h>
  3. #include <sys/mman.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <string.h>
  8.  
  9. int main(){
  10. int fd = open("/dev/tankai_dev",O_RDWR,0);
  11. if(fd < 0) perror("testdriver");
  12. printf("TK------->>>fd is %dn",fd);
  13. char buf[20];
  14. int result = read(fd,&buf,3);
  15. printf("TK------->>>readresult is %d,buf is %sn",result,buf);
  16. strcpy(buf,"123");
  17. result = write(fd,&buf,3);
  18. printf("TK------->>>writeresult is %d,buf is %sn",result,buf);
  19. close(fd);
  20. return 0;
  21. }

Android.mk

  1. LOCAL_PATH:= $(call my-dir)
  2. include $(CLEAR_VARS)
  3.  
  4. LOCAL_SRC_FILES:=
  5. testdriver.c
  6.  
  7. LOCAL_SHARED_LIBRARIES :=
  8. libutils
  9.  
  10. LOCAL_MODULE:= testdriver
  11.  
  12. LOCAL_MODULE_TAGS := optional
  13.  
  14. include $(BUILD_EXECUTABLE)

二、自动创建

放通驱动中“创建”和“结束”部分代码;就不需要在执行mknod命令,设备节点会被创建,见:Linux设备节点创建》内核kobject上报uevent过滤规则 及 《Linux设备节点创建》用户空间ueventd创建设备节点规则。

1
 条评论
相关内容推荐