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;
}
设计资源 培训 开发板 精华推荐
- 好书共读:《硬件设计指南:从器件认知到手机基带设计》
- 泰克多媒体总线专题之《DDR Memory》,下载赢好礼!
- 以旧换新!100套TI MSPM0整装待发,升级你的装备!
- 今天下午1点开播!市场上最广泛的光学传感方案组合—艾迈斯欧司朗光学技术论坛
- 有奖直播 | ST25 NFC新产品及应用方案介绍 报名中
- 观看TI IOT解决方案研讨会 答题即可赢取更多精美好礼!
- 有奖直播【Keysight World Tech Day 2023分论坛——汽车自动驾驶与新能源】
- Keysight 有奖直播 | 基于数字孪生的软件工具,助力射频子系统验证
- Altera Cyclone V 开发板全体验
- 有奖调查 | 您是如何采购或选择电子元器件的?