1. 程式人生 > >《Linux裝置節點建立》手動與自動建立裝置節點

《Linux裝置節點建立》手動與自動建立裝置節點

一、手動建立

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)

二、自動建立