《Linux设备节点创建》手动与自动创建设备节点

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 dev\n");
 //注册设备
 rc = register_chrdev(TEST_MAJOR,"test_dev",&led_fops);
 if (rc <0){  
   printk ("register %s char dev error\n","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 canshu\n");
    return -1;
  }
  char *devname = argv[1];
  printf("devname is %s\n",devname);
  int devnum = -1;
  sscanf(argv[2],"%d",&devnum);
  printf("devnum is %d\n",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 %d\n",fd);
  char buf[20];
  int result = read(fd,&buf,3);
  printf("TK------->>>readresult is %d,buf is %s\n",result,buf);
  strcpy(buf,"123");
  result = write(fd,&buf,3);
  printf("TK------->>>writeresult is %d,buf is %s\n",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创建设备节点规则。

你可能感兴趣的:(《Linux设备节点创建》手动与自动创建设备节点)