linux字符驱动之自动创建设备节点

上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了。

上一节文章链接:http://blog.csdn.net/lwj103862095/article/details/17468587

问:能不能让系统自动创建设备节点?

答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。

问:文件系统里,在哪里设置了mdev机制?

答:在etc/init.d/rcS文件里有一句:

echo /sbin/mdev > /proc/sys/kernel/hotplug

问:在驱动程序里面如何编写程序,让系统自动创建设备节点?

答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。


详细请参考驱动源码:

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/module.h>
#include <linux/device.h> 	//class_create

static struct class *firstdrv_class;
static struct device *firstdrv_device;

int major;
static int first_drv_open(struct inode * inode, struct file * filp)
{
	printk("first_drv_open\n");
	return 0;
}
static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
{
	printk("first_drv_write\n");
	return 0;
}

/* File operations struct for character device */
static const struct file_operations first_drv_fops = {
	.owner		= THIS_MODULE,
	.open		= first_drv_open,
	.write      = first_drv_write,
};

/* 驱动入口函数 */
static int first_drv_init(void)
{
	/* 主设备号设置为0表示由系统自动分配主设备号 */
	major = register_chrdev(0, "first_drv", &first_drv_fops);

	/* 创建firstdrv类 */
	firstdrv_class = class_create(THIS_MODULE, "firstdrv");

	/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
	firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
	return 0;
}

/* 驱动出口函数 */
static void first_drv_exit(void)
{
	unregister_chrdev(major, "first_drv");
	device_unregister(firstdrv_device);  //卸载类下的设备
	class_destroy(firstdrv_class);		//卸载类
}

module_init(first_drv_init);  //用于修饰入口函数
module_exit(first_drv_exit);  //用于修饰出口函数	

MODULE_AUTHOR("LWJ");
MODULE_DESCRIPTION("Just for Demon");
MODULE_LICENSE("GPL");  //遵循GPL协议


注意事项:

1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。

2.使用的函数名可能也不一样,例如:

韦老师是这样子创建类和创建类的设备:

一、定义

static struct class *firstdrv_class;
static struct class_device *firstdrv_class_dev;

二、入口函数里

firstdrv_class = class_create(THIS_MODULE, "firstdrv");
firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */

三、出口函数里

class_device_unregister(firstdrv_class_dev);
class_destroy(firstdrv_class);


而在linux2.6.30.4里,并没有class_device_createclass_device_unregister函数

我是这样子创建类和创建类的设备:

一、定义

static struct class *firstdrv_class;
static struct device *firstdrv_device;

二、入口函数里

/* 创建firstdrv类 */

firstdrv_class = class_create(THIS_MODULE, "firstdrv");


/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");

三、出口函数里

device_unregister(firstdrv_device);  //卸载类下的设备
class_destroy(firstdrv_class); //卸载类


linux2.6.30.4使用device_create函数替代class_device_create函数;

使用device_unregister函数替代class_device_unregister函数。


测试程序和Makefile没有修改,故再不贴。

上一节文章链接:http://blog.csdn.net/lwj103862095/article/details/17468587

测试步骤:

[WJ2440]# ls
Qt            driver_test   lib           root          udisk
TQLedtest     etc           linuxrc       sbin          usr
app_test      first_drv.ko  mnt           sddisk        var
bin           first_test    opt           sys           web
dev           home          proc          tmp
[WJ2440]# ls -l /dev/xxx
ls: /dev/xxx: No such file or directory
[WJ2440]# insmod first_drv.ko 
[WJ2440]# lsmod
first_drv 1912 0 - Live 0xbf000000
[WJ2440]# ls -l /dev/xxx
crw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx
[WJ2440]# 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
 81 video4linux
 89 i2c
 90 mtd
116 alsa
128 ptm
136 pts
180 usb
188 ttyUSB
189 usb_device
204 tq2440_serial
252 first_drv
253 usb_endpoint
254 rtc

Block devices:
259 blkext
  7 loop
  8 sd
 31 mtdblock
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
[WJ2440]# cd /sys/class/
[WJ2440]# ls
bdi           i2c-adapter   misc          scsi_device   usb_endpoint
block         i2c-dev       mmc_host      scsi_disk     usb_host
firmware      ieee80211     mtd           scsi_host     vc
firstdrv      input         net           sound         video4linux
graphics      mem           rtc           tty           vtconsole
[WJ2440]# cd firstdrv/
[WJ2440]# ls
xxx
[WJ2440]# cd xxx/
[WJ2440]# ls 
dev        subsystem  uevent
[WJ2440]# cat dev 
252:0
[WJ2440]# cat uevent 
MAJOR=252
MINOR=0
[WJ2440]# cd /   
[WJ2440]# ./first_test 
first_drv_open
first_drv_write
[WJ2440]# 


  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值