一、手动创建
1.驱动模块
test_driver.c
//#include
#include
#include
#include
#include
#include
#include
#include
#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
#include
#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
#include
#include
#include
#include
#include
#include
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)
二、自动创建