特种设备培训学习,设备管理学习总结
学习tty设备驱动,我们要先会加载和卸载此设备。 tty设备驱动有一个很重要的结构体:tty_driver。它用来注册和注销一个 tty 驱动到 tty 内核。 linux2.6.28/include/linux/tty_driver.h: struct tty_driver { 272 int magic; /* magic number for this structure */ 273 struct kref kref; /* Reference management */ 274 struct cdev cdev; 275 struct module *owner; 276 const char *driver_name; 277 const char *name; 278 int name_base; /* offset of printed name */ 279 int major; /* major device number */ 280 int minor_start; /* start of minor device number */ 281 int minor_num; /* number of *possible* devices */ 282 int num; /* number of devices allocated */ 283 short type; /* type of tty driver */ 284 short subtype; /* subtype of tty driver */ 285 struct ktermios init_termios; /* Initial termios */ 286 int flags; /* tty driver flags */ 287 struct proc_dir_entry *proc_entry; /* /proc fs entry */ 288 struct tty_driver *other; /* only used for the PTY driver */ 289 290 /* 291 * Pointer to the tty data structures 292 */ 293 struct tty_struct **ttys; 294 struct ktermios **termios; 295 struct ktermios **termios_locked; 296 void *driver_state; 297 298 /* 299 * Driver methods 300 */ 301 302 const struct tty_operations *ops; 303 struct list_head tty_drivers; 304};
308 extern struct tty_driver *alloc_tty_driver(int lines); 这个函数返回tty_driver指针,其参数为要分配的设备数量,line会被赋值给tty_driver的num成员. 为创建一个 struct tty_driver, 函数 alloc_tty_driver 必须用这个驱动作为参数而支持的 tty 设备号来调用.
以下函数用来注册tty设备和驱动: linux2.6.28/include/linux/tty.h: 343 extern int tty_register_driver(struct tty_driver *driver); 注册tty驱动 344 extern int tty_unregister_driver(struct tty_driver *driver); 注销tty驱动 345 extern struct device *tty_register_device(struct tty_driver *driver, 346 unsigned index, struct device *dev); 注册tty设备 347 extern void tty_unregister_device(struct tty_driver *driver, unsigned index); 注销tty设备
下面一个例子来加载和卸载tty模块:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/tty.h> /*注意:tty.h和tty_driver.h顺序不能颠倒,必须是tty.h在tty_driver.h前面。一旦顺序颠倒,就会提示有错误。*/
#include <linux/tty_driver.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/serial_reg.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lan");
#define TTY_LAN_MINORS_NUM 5
#define TTY_LAN_MAJOR 202
static struct tty_driver *tty_lan_driver;
static int tty_lan_open(struct tty_struct *tty, struct file *filp);
static struct tty_operations tty_lan_ops = {
.open = tty_lan_open,
};
{
int i;
int retval;
tty_lan_driver = alloc_tty_driver(TTY_LAN_MINORS_NUM);
if(!tty_lan_driver)
return -ENOMEM;
tty_lan_driver->owner = THIS_MODULE;
tty_lan_driver->driver_name = "tty_lan";
tty_lan_driver->name = "ttty_lan";
tty_lan_driver->major = TTY_LAN_MAJOR,
tty_lan_driver->minor_start = 0;
tty_lan_driver->type = TTY_DRIVER_TYPE_SERIAL;
tty_lan_driver->subtype = SERIAL_TYPE_NORMAL;
tty_lan_driver->flags = TTY_DRIVER_REAL_RAW;
tty_lan_driver->init_termios = tty_std_termios;
tty_lan_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
retval = tty_register_driver(tty_lan_driver);
if(retval){
printk(KERN_ERR"Failed to register tty_lan_driver!\n");
put_tty_driver(tty_lan_driver);
return retval;
}
for(i = 0; i < TTY_LAN_MINORS_NUM; i++)
tty_register_device(tty_lan_driver, i, NULL);
return 0;
}
static int tty_lan_open(struct tty_struct *tty, struct file *filp)
{
return 0;
}
static void __exit tty_lan_exit(void)
{
int i;
for(i = 0; i < TTY_LAN_MINORS_NUM; i++)
tty_unregister_device(tty_lan_driver, i);
tty_unregister_driver(tty_lan_driver);
}
module_init(tty_lan_init);
module_exit(tty_lan_exit);
Makefile:
UNAME = $(shell uname -r)
LINUX_PATH = /lib/modules/$(UNAME)/build
obj-m = tty_lan.o
all:
$(MAKE) -C $(LINUX_PATH) M=$(PWD) modules
clean:
$(MAKE) -C $(LINUX_PATH) M=$(PWD) clean
我们编译并加载此模块后,观察如下文件: $ cat /proc/tty/drivers /dev/tty /dev/tty 5 0 system:/dev/tty /dev/console /dev/console 5 1 system:console /dev/ptmx /dev/ptmx 5 2 system /dev/vc/0 /dev/vc/0 4 0 system:vtmaster tty_lan /dev/ttty_lan 202 0-4 serial rfcomm /dev/rfcomm 216 0-255 serial serial /dev/ttyS 4 64-111 serial pty_slave /dev/pts 136 0-1048575 pty:slave pty_master /dev/ptm 128 0-1048575 pty:master unknown /dev/tty 4 1-63 console 红色字体那一行就是我的tty设备。
我创建了5个设备。到/dev目录下看看吧: $ ls -l /dev/ttty_lan* crw-rw---- 1 root root 202, 0 2010-07-26 16:40 /dev/ttty_lan0 crw-rw---- 1 root root 202, 1 2010-07-26 16:40 /dev/ttty_lan1 crw-rw---- 1 root root 202, 2 2010-07-26 16:40 /dev/ttty_lan2 crw-rw---- 1 root root 202, 3 2010-07-26 16:40 /dev/ttty_lan3 crw-rw---- 1 root root 202, 4 2010-07-26 16:40 /dev/ttty_lan4
OK,tty设备的创建已经完成。后面就要对tty设备文件进行操作了。