1、终端设备
在Linux系统中,终端是一种字符型设备,它有多种类型,通常使用tty来简称各种类型的终端设备。tty是Teletype的缩写,Teletype是最早出现的一种终端设备,很像电传打字机,是由Teletype公司生产的。
Linux中包含如下几类终端设备:
1).串行端口终端(/dev/ttySn)
使用计算机串行端口连接的终端设备。串行端口对应的设备名称是/dev/ttySn。如/dev/ttyS0、/dev/ttyS1等,设备号分别是(4,0)、(4,1)
2).伪终端(/dev/pty/)
显示器通常称为控制台终端,若当前进程有控制终端,则/dev/tty就是当前进程的控制终端的设备特殊文件。可以使用命令“ps-ax”查看进程与哪个控制终端相连,使用命令“tty”查看它具体对应哪个实际终端设备。
3).控制台终端(/dev/ttyn, /dev/console)
2、Linux内核tty层次结构
(1)、tty线程规程
以特殊的方式格式化从一个用户或者硬件收到的数据,这种格式化常常采用一个协议转换的形式,如PPP、Bluetooth。
(2)、tty设备发送数据流程
tty核心从一个用户获取将要发送给一个tty设备的数据,tty核心将数据传递给tty线路规程驱动,接着数据被传递到tty驱动,tty驱动将数据转换为可以发送的硬件格式。
(3)、tty设备接收数据流程
从tty硬件接收到的数据向上交给tty驱动,进入tty线路规程驱动,再进入tty核心,在此被用户获取。尽管tty核心与tty之间的数据传输会经历tty线路规程的转换,但是tty驱动与tty核心之间也可以直接传输数据。
(4)、上图第一部分,因为终端是一种字符设备,所以要按字符设备的要求来注册,并有对应的file_operations结构体,用于对设备进行操作。
注册的方法有两种:
(1)、在drivers/char/Tty_io.c中定义:
static const struct file_operations tty_fops = {
.llseek = no_llseek,
.read = tty_read,
.write = tty_write,
.poll = tty_poll,
.unlocked_ioctl= tty_ioctl,
.compat_ioctl = tty_compat_ioctl,
.open = tty_open,
.release = tty_release,
.fasync = tty_fasync,
};
此结构体在下面初始化函数中被赋值给对应的字符设备tty
可以在注册tty_driver结构体实例时进行,一般用此方法。
/*
* Called by a tty driver to register itself.
*/
int tty_register_driver(struct tty_driver *driver)
{
int error;
int i;
dev_t dev;
void **p = NULL;
if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
if (!p)
return -ENOMEM;
}
if (!driver->major) {
error = alloc_chrdev_region(&dev, driver->minor_start,
driver->num, driver->name);
if (!error) {
driver->major = MAJOR(dev);
driver->minor_start = MINOR(dev);
}
} else {
dev = MKDEV(driver->major, driver->minor_start);
error = register_chrdev_region(dev, driver->num, driver->name);
}
if (error < 0) {
kfree(p);
return error;
}
if (p) {
driver->ttys = (struct tty_struct **)p;
driver->termios = (struct ktermios **)(p + driver->num);
} else {
driver->ttys = NULL;
driver->termios = NULL;
}
cdev_init(&driver->cdev, &tty_fops);
driver->cdev.owner = driver->owner;
error = cdev_add(&driver->cdev, dev, driver->num);
if (error) {
unregister_chrdev_region(dev, driver->num);
driver->ttys = NULL;
driver->termios = NULL;
kfree(p);
return error;
}
mutex_lock(&tty_mutex);
list_add(&driver->tty_drivers, &tty_drivers);
mutex_unlock(&tty_mutex);
if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
for (i = 0; i < driver->num; i++)
tty_register_device(driver, i, NULL);
}
proc_tty_register_driver(driver);
driver->flags |= TTY_DRIVER_INSTALLED;
return 0;
}
上一篇:linux串口终端驱动——s3c6410平台(四)
下一篇:linux串口终端驱动——s3c6410平台(三)
推荐阅读最新更新时间:2024-11-11 11:44
设计资源 培训 开发板 精华推荐
- OP113FSZ-REEL 超低噪声、单电源仪表放大器的典型应用
- 使用 2.5V 外部基准的 AD5327 4 缓冲、12 位 DAC 的典型应用
- number plate
- EVAL-AD5767SD2Z,用于评估 AD5767 16 通道、12 位串行输入、电压输出 DAC 的评估板
- 使用 ON Semiconductor 的 LV4991M 的参考设计
- MC78M08BTG 8V 电流升压稳压器的典型应用
- LTC3701 的典型应用 - 2 相、低输入电压、双路降压型 DC/DC 控制器
- LT8609AIMSE 超低 EMI 5V/2A 降压转换器的典型应用电路
- 用电器识别分析装置
- LT1511,具有输入电流限制的可编程恒流 / 恒压电池充电器