创建设备节点--手动方法
Android2.3及Linux2.6.29内核模拟器版本编译与调试
一、手动创建
1.驱动模块
test_driver.c
- //#include <linux/devfs_fs_kernel.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/uaccess.h>
- #include <linux/miscdevice.h>
- #include <linux/fs.h>
- #include <linux/init.h>
- #include <linux/platform_device.h>
- #define TEST_MAJOR 240
- //动态设备节点
- //struct class *mymodule_class;
- //结束
- static int test_led_open(struct inode *inode, struct file *file)
- {
- printk("#########open######n");
- return 0;
- }
- static int test_led_close(struct inode *inode, struct file *file)
- {
- printk("#########release######n");
- return 0;
- }
- static int test_led_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
- {
- printk("#########read######n");
- return count;
- }
- static int test_led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
- {
- printk("#########write######n");
- return count;
- }
- static struct file_operations led_fops = {
- .owner = THIS_MODULE,
- .open = test_led_open,
- .release = test_led_close,
- .read = test_led_read,
- .write = test_led_write,
- };
- static int __init test_drv_init(void)
- {
- int rc;
- printk("test_driver devn");
- //注册设备
- rc = register_chrdev(TEST_MAJOR,"test_dev",&led_fops);
- if (rc <0){
- printk ("register %s char dev errorn","led");
- goto out_chrdev;
- }
- //devfs文件系统创建
- /*
- devfs_mk_cdev( MKDEV(TEST_MAJOR, 0),
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, "test_dev");
- */
- //结束
- //实现动态创建
- //mymodule_class = class_create(THIS_MODULE, "test_dev");//在/sys/class/下创建“test_dev”目录
- //device_create(mymodule_class, NULL, MKDEV(TEST_MAJOR, 0), NULL, "tankai_dev"); //在/dev/下创建“tankai_dev”文件
- //结束
- printk ("ok!n");
- return 0;
- out_chrdev:
- unregister_chrdev(TEST_MAJOR, "mymodule");
- }
- static void __exit test_drv_exit(void)
- { //动态设备节点
- //device_destroy(mymodule_class, MKDEV(TEST_MAJOR, 0));
- //class_destroy(mymodule_class);
- //结束
- unregister_chrdev(TEST_MAJOR, "test_dev");
- }
- module_init(test_drv_init);
- module_exit(test_drv_exit);
- MODULE_AUTHOR("tank");
- MODULE_LICENSE("GPL");
Makefile
- obj-m := test_driver.o
- PWD := $(shell pwd)
- #KERNELDIR := /usr/src/linux-headers-3.0.0-26-generic/
- KERNELDIR := /home/android2.3/android2.3_kernel/
- default:
- $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
- # cp -rf mini.ko ../module/
- # cp -rf lddbus.ko ../module/
- clean:
- rm *.mod.c *.o *.ko *.bak modules.* Module.*
2.Android模拟器没有mknod命令,我们实现它
mknod.c
- #include <stdio.h>
- #include <fcntl.h>
- #define S_IFCHR 0020000
- int main(int argc,char *argv[])
- {
- if(argc != 3){
- printf("error:Two canshun");
- return -1;
- }
- char *devname = argv[1];
- printf("devname is %sn",devname);
- int devnum = -1;
- sscanf(argv[2],"%d",&devnum);
- printf("devnum is %dn",devnum);
- if(mknod(devname,S_IFCHR|0666,makedev(devnum,0))!=0)
- perror("mknod");
- return 0;
- }
Android.mk
- LOCAL_PATH:= $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:=
- mknod.c
- LOCAL_SHARED_LIBRARIES :=
- libutils
- LOCAL_MODULE:= mknod
- LOCAL_MODULE_TAGS := optional
- include $(BUILD_EXECUTABLE)
查看:cat /proc/devices
结果:
- Character devices:
- 1 mem
- 4 /dev/vc/0
- 4 tty
- 5 /dev/tty
- 5 /dev/console
- 5 /dev/ptmx
- 7 vcs
- 10 misc
- 13 input
- 14 sound
- 29 fb
- 90 mtd
- 116 alsa
- 128 ptm
- 136 pts
- 240 test_dev
- 253 ttyS
- 254 rtc
- Block devices:
- 1 ramdisk
- 259 blkext
- 7 loop
- 31 mtdblock
- 43 nbd
- 179 mmc
- 254 device-mapper
执行:./mknod /dev/tankai_dev 240
//这里只需要给出主设备号,主设备号相同的设备使用同一驱动程序;只是加入次设备号后可以实现一个驱动,多个设备使用的情况。这个目前我们的驱动中没有实现;因此,次设备号可以随便。
ll /dev/tankai_dev
结果:
- crw-rw-rw- root root 240, 0 2013-10-16 09:54 tankai_dev
3.测试用例
testdriver.c
- #include <fcntl.h>
- #include <stdlib.h>
- #include <sys/mman.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <string.h>
- int main(){
- int fd = open("/dev/tankai_dev",O_RDWR,0);
- if(fd < 0) perror("testdriver");
- printf("TK------->>>fd is %dn",fd);
- char buf[20];
- int result = read(fd,&buf,3);
- printf("TK------->>>readresult is %d,buf is %sn",result,buf);
- strcpy(buf,"123");
- result = write(fd,&buf,3);
- printf("TK------->>>writeresult is %d,buf is %sn",result,buf);
- close(fd);
- return 0;
- }
Android.mk
- LOCAL_PATH:= $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:=
- testdriver.c
- LOCAL_SHARED_LIBRARIES :=
- libutils
- LOCAL_MODULE:= testdriver
- LOCAL_MODULE_TAGS := optional
- include $(BUILD_EXECUTABLE)
二、自动创建
放通驱动中“创建”和“结束”部分代码;就不需要在执行mknod命令,设备节点会被创建,见:《Linux设备节点创建》内核kobject上报uevent过滤规则 及 《Linux设备节点创建》用户空间ueventd创建设备节点规则。
1