linux串口终端驱动——s3c6410平台(二)

发布者:ShiningSmile最新更新时间:2022-06-15 来源: eefocus关键字:linux 手机看文章 扫描二维码
随时随地手机看文章

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 引用地址:linux串口终端驱动——s3c6410平台(二)

上一篇:linux串口终端驱动——s3c6410平台(四)
下一篇:linux串口终端驱动——s3c6410平台(三)

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved