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

来源:互联网 发布:mac珊瑚橘和mac西柚色 编辑:程序博客网 时间:2024/04/29 12:36

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.oPWD := $(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 0020000int 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.cLOCAL_SHARED_LIBRARIES := \libutils LOCAL_MODULE:= mknodLOCAL_MODULE_TAGS := optionalinclude $(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 mtd116 alsa128 ptm136 pts240 test_dev253 ttyS254 rtcBlock devices:  1 ramdisk259 blkext  7 loop 31 mtdblock 43 nbd179 mmc254 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.cLOCAL_SHARED_LIBRARIES := \libutils LOCAL_MODULE:= testdriverLOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE)

二、自动创建

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

原创粉丝点击