精华内容
下载资源
问答
  • tty

    2019-04-23 18:47:16
    tty_insert_flip_string(porty, (u8 *)rx_buf, i); tty_flip_buffer_push(porty); --> void tty_flip_buffer_push(struct tty_port *port) { tty_schedule_flip(port);...

             tty_insert_flip_string(porty, (u8 *)rx_buf, i);
             tty_flip_buffer_push(porty); 

     

    -->

    void tty_flip_buffer_push(struct tty_port *port)
    {
            tty_schedule_flip(port);                                                                                                                                                                            
    }

     

    -->

    void tty_schedule_flip(struct tty_port *port)
    {
            struct tty_bufhead *buf = &port->buf;

            /* paired w/ acquire in flush_to_ldisc(); ensures
             * flush_to_ldisc() sees buffer data.
             */
            smp_store_release(&buf->tail->commit, buf->tail->used);
            queue_work(system_unbound_wq,  &buf->work);                                                                                                                                                          
    }

     

    ---------------------------------------------------------------------------->

    INIT_WORK(&buf->work, flush_to_ldisc);

     

    -->

    static void flush_to_ldisc(struct work_struct *work)
    {

    count = receive_buf(disc, head, count);

    }

     

    -->

    static int
    receive_buf(struct tty_ldisc *ld, struct tty_buffer *head, int count)                                                                                                                                       
    {
            unsigned char *p = char_buf_ptr(head, head->read);
            char          *f = NULL;

            if (~head->flags & TTYB_NORMAL)
                    f = flag_buf_ptr(head, head->read);

            return tty_ldisc_receive_buf(ld, p, f, count);
    }

    -->

    int tty_ldisc_receive_buf(struct tty_ldisc *ld, unsigned char *p,
                              char *f, int count)
    {                       
            if (ld->ops->receive_buf2)
                    count = ld->ops->receive_buf2(ld->tty, p, f, count);
            else {          
                    count = min_t(int, count, ld->tty->receive_room);
                    if (count && ld->ops->receive_buf)
                            ld->ops->receive_buf(ld->tty, p, f, count);
            }
            return count;
    }

    -->

    2441 static struct tty_ldisc_ops n_tty_ops = {
    2442         .magic           = TTY_LDISC_MAGIC,
    2443         .name            = "n_tty",
    2444         .open            = n_tty_open,
    2445         .close           = n_tty_close,
    2446         .flush_buffer    = n_tty_flush_buffer,
    2447         .read            = n_tty_read,
    2448         .write           = n_tty_write,
    2449         .ioctl           = n_tty_ioctl,
    2450         .set_termios     = n_tty_set_termios,
    2451         .poll            = n_tty_poll,
    2452         .receive_buf     =  n_tty_receive_buf,                                                                                                                                                          
    2453         .write_wakeup    = n_tty_write_wakeup,
    2454         .receive_buf2    = n_tty_receive_buf2,
    2455 };


    -->

    static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,                                                                                                                              
                                  char *fp, int count)
    {
            n_tty_receive_buf_common(tty, cp, fp, count, 0);
    }

    --->

    static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
                              char *fp, int count)
    {
            struct n_tty_data *ldata = tty->disc_data;
            bool preops = I_ISTRIP(tty) || (I_IUCLC(tty) && L_IEXTEN(tty));

            if (ldata->real_raw)
                    n_tty_receive_buf_real_raw(tty, cp, fp, count);
            else if (ldata->raw || (L_EXTPROC(tty) && !preops))
                    n_tty_receive_buf_raw(tty, cp, fp, count);


    -->

     

    static void
    n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp,
                               char *fp, int count)
    {
            struct n_tty_data *ldata = tty->disc_data;
            size_t n, head;
            
            head = ldata->read_head & (N_TTY_BUF_SIZE - 1);
            n = min_t(size_t, count, N_TTY_BUF_SIZE - head);
            memcpy(read_buf_addr(ldata, head), cp, n);
            ldata->read_head += n;
            cp += n;
            count -= n;
            
            head = ldata->read_head & (N_TTY_BUF_SIZE - 1);
            n = min_t(size_t, count, N_TTY_BUF_SIZE - head);
            memcpy(read_buf_addr(ldata, head), cp, n);
            ldata->read_head += n;
    }

     

    展开全文
  • TTY

    2017-02-24 21:51:27
    TTYtty是Teletype的缩写,Teletype是最早出现的一种终端设备,很象电传打字机,是由Teletype公司生产的。后来,出现了各种类型的终端设备,这些终端设备都统称为TTY,即终端..../dev/tty /dev/tty16 /dev/tty2

    参考文档

    Linux 设备文件简介
    /dev/tty, /dev/console and /dev/ttyN
    Linux的终端类型


    TTY

    tty是Teletype的缩写,Teletype是最早出现的一种终端设备,很象电传打字机,是由Teletype公司生产的。后来,出现了各种类型的终端设备,这些终端设备都统称为TTY,即终端.

    所有的终端都是字符型设备,分为很多类型.


    /dev目录下的终端文件

    linux@ubuntu:~/work/tmp$ ls /dev/tty*
    /dev/tty    /dev/tty16  /dev/tty24  /dev/tty32  /dev/tty40  /dev/tty49  /dev/tty57  /dev/tty8       /dev/ttyS14  /dev/ttyS22  /dev/ttyS30
    /dev/tty0   /dev/tty17  /dev/tty25  /dev/tty33  /dev/tty41  /dev/tty5   /dev/tty58  /dev/tty9       /dev/ttyS15  /dev/ttyS23  /dev/ttyS31
    /dev/tty1   /dev/tty18  /dev/tty26  /dev/tty34  /dev/tty42  /dev/tty50  /dev/tty59  /dev/ttyprintk  /dev/ttyS16  /dev/ttyS24  /dev/ttyS4
    /dev/tty10  /dev/tty19  /dev/tty27  /dev/tty35  /dev/tty43  /dev/tty51  /dev/tty6   /dev/ttyS0      /dev/ttyS17  /dev/ttyS25  /dev/ttyS5
    /dev/tty11  /dev/tty2   /dev/tty28  /dev/tty36  /dev/tty44  /dev/tty52  /dev/tty60  /dev/ttyS1      /dev/ttyS18  /dev/ttyS26  /dev/ttyS6
    /dev/tty12  /dev/tty20  /dev/tty29  /dev/tty37  /dev/tty45  /dev/tty53  /dev/tty61  /dev/ttyS10     /dev/ttyS19  /dev/ttyS27  /dev/ttyS7
    /dev/tty13  /dev/tty21  /dev/tty3   /dev/tty38  /dev/tty46  /dev/tty54  /dev/tty62  /dev/ttyS11     /dev/ttyS2   /dev/ttyS28  /dev/ttyS8
    /dev/tty14  /dev/tty22  /dev/tty30  /dev/tty39  /dev/tty47  /dev/tty55  /dev/tty63  /dev/ttyS12     /dev/ttyS20  /dev/ttyS29  /dev/ttyS9
    /dev/tty15  /dev/tty23  /dev/tty31  /dev/tty4   /dev/tty48  /dev/tty56  /dev/tty7   /dev/ttyS13     /dev/ttyS21  /dev/ttyS3
    linux@ubuntu:~/work/tmp$ ls -l /dev/tty*
    crw-rw-rw- 1 root tty     5,  0  2月 23 22:24 /dev/tty
    以下省略,都是字符文件
    linux@ubuntu:~/work/tmp$ ls /dev/pts/
    0  1  2  4  6  7  ptmx
    linux@ubuntu:~/work/tmp$ ll /dev/console  
    crw------- 1 root root 5, 1  2月 23 20:51 /dev/console
    

    linux中的设备

    Linux 中的设备按照存取方式的不同,可以分为两种:

    • 字符设备

      无缓冲且只能顺序存取

    • 块设备

      有缓冲且可以随机(乱序)存取

    而按照是否对应物理实体,也可以分为两种:

    • 物理设备

      对实际存在的物理硬件的抽象

    • 虚拟设备

      不依赖于特定的物理硬件,仅是内核自身提供的某种功能

    无论是哪种设备,在 /dev 目录下都有一个对应的文件(节点),并且每个设备文件都必须有主/次设备号,主设备号相同的设备是同类设备,使用同一个驱动程序(虽然目前的内核允许多个驱动共享一个主设备号,但绝大多数设备依然遵循一个驱动对应一个主设备号的原则)。可以通过 cat /proc/devices 命令查看当前已经加载的设备驱动程序的主设备号。

    注意:在 /dev 目录下除了各种设备节点之外还通常还会存在:FIFO管道、Socket、软/硬连接、目录。这些东西并不是设备文件,因此也就没有主/次设备号。


    终端类型

    之前说了,终端都是字符类型,那么按照是否对应物理实体的话,分为物理设备和虚拟设备两种

    那么有以下几种类型

    1. 虚拟控制台

      对应下面几个文件
      /dev/tty
      /dev/tty0
      /dev/console
      /dev/tty1 - /dev/tty63
      
      /dev/tty代指当前TTY设备
      echo hello > /dev/tty 会打印hello到当前屏幕 
      /dev/tty0
      echo hello > /dev/tty0 会打印hello到当前屏幕(注意只在/dev/tty1下实验成功)
      /dev/console是一个虚拟的tty,它映射到真正的tty上
      echo hello > /dev/console 会打印hello 到当前屏幕(注意只在/dev/tty1下实验成功)
      
      可以在Ubuntu界面下键入组合键ctrl + alt + F1,然后登录,然后输入命令tty,会输出/dev/tty1
      
      /dev/console是个只输出的设备,功能很简单,只能在内核中访问
      tty是char设备,可以被用户程序访问。
      实际的驱动比如串口对一个物理设备会注册两次,一个是tty,一个是console,并通过在console的结构中记录tty的主次设备号建立了联系。
      
      在内核中,tty和console都可以注册多个。当内核命令行上指定console=ttyS0之类的参数时,首先确定了printk实际使用那个 console作为输出,其次由于console和tty之间的对应关系,打开/dev/console时,就会映射到相应的tty上。用一句话说: /dev/console将映射到默认console对应的tty上。
      
      /dev/console是一个虚拟的tty,它映射到真正的tty上,console有多种含义,这里特指printk输出的设备,驱动使用register_console注册一个console。
      
      tty1 –tty6等称为虚拟终端,而tty0则是当前所使用虚拟终端的一个别名,系统所产生的信息会发送到该终端上。因此不管当前正在使用哪个虚拟终端,系统信息都会发送到控制台终端上。
      所以说tty0 和console是一样的?
      
      串口TTY和虚拟TTY是两种实际常用的TTY。串口TTY基于串口构建,设备节点的形式为/dev/ttyS<N>的形式,一般主设备号为4,<N>一般为64~255。虚拟TTY用于给非TTY的设备提供TTY形式的接口,一般主设备号为4,<N>一般为0~63。
      
      
    2. 串口

      对应下下面几个文件
      /dev/ttyS0 - /devttyS191
      
    3. USB转串口

      对应下面几个文件
      /dev/ttyUSB0 - ?
      
    4. 伪终端

      对应下面几个文件
      /dev/pts/0 -/dev/pts/14 ?
      通过ssh 上去的就是这个终端
      其实在Ubuntu界面下打开的终端也是这个终端
      
    5. 其他终端

      /dev/ttyprintk
      

    展开全文
  • tty-file breaks tty-which

    2020-12-08 18:40:48
    <strong>tty</strong>: 0.6.0 <strong>tty-which</strong>: 0.2.1 <strong>OS</strong>: Linux (Arch) <p>With 0.5.0, I could use <code>TTY::Which</code> by requiring <code>tty</code> e.g.: <pre><code>ruby ...
  • tty login

    2020-11-28 11:23:35
    <p>I use startx to open my x enviroment, but post-login in the tty, it is messed up. Theres an issue with vimbed indicated in red at the bottom, and the first letter i type is the only letter any of ...
  • Tty detection

    2020-11-25 11:31:31
    <div><p>This PR makes two changes: use ...re running in a tty, and changes the non-tty logic to loop forever when loops is set to 0.</p><p>该提问来源于开源项目:jmhobbs/terminal-parrot</p></div>
  • /dev/tty设备 这个设备表示的是控制终端,如果当前的shell登录环境有关联控制终端,那么执行它就可以看到回显。 echo test > /dev/tty 它其实是一个当前控制终端的一个别名,实际控制终端可以是伪终端(/dev/pts/...

    /dev/tty设备

    这个设备表示的是控制终端,如果当前的shell登录环境有关联控制终端,那么执行它就可以看到回显。
    echo test > /dev/tty
    它其实是一个当前控制终端的一个别名,实际控制终端可以是伪终端(/dev/pts/x),也可以是虚拟控制台(/dev/ttyx)。/dev/tty有些类似于到实际所使用终端设备的一个链接

    /dev/tty0设备

    tty0表示的是当前虚拟控制台的一个别名,而实际的虚拟控制台是tty1…ttyn。
    其中tty1和tty2为X窗口系统,其余为虚拟字符终端。

    /dev/console设备

    这个设备表示的是系统控制台,主要用于接收系统message的,系统消息一般不会被发送到tty上,而是发送给console设备上,当然我们可以配置console为一个tty,这样系统消息就会被发送到一个tty终端上,通过cmdline指定console=tty0,此时/dev/console相当于是/dev/tty0的一个别名。同样我们也可以指定它为一个串口设备,通过设定console=/dev/ttyS1进行指定,此时/dev/console相当于是/dev/ttyS1的一个别名。

    展开全文
  • tty实用程序 Tty-utility是python程序的控制台
  • tty驱动

    2020-04-05 14:55:05
    参考:http://www.wowotech.net/tty_framework/435.html 一、框架 用户层只要初始化后注册进tty_core即可 二、读写流程 ...tty_port[struct tty_bufhead buf]会唤醒 2.写 usr_buf--->copy到tty_st...

    参考:http://www.wowotech.net/tty_framework/435.html

    一、框架 

    用户层只要初始化后注册进tty_core即可 

    二、读写流程

    1. 读:

    usr_buf--->ld线程里阻塞读---> tty_port[struct tty_bufhead    buf]会唤醒

    2.写

    usr_buf--->copy到tty_struct的buf----->copy到tty_port的buf(可选,也可以直接拷贝到驱动自定义的buf里

    3. open关键,通过子设备号,找到tty_driver,然后初始化tty_struct,填充到tty_driver的tty_struct数组里,并且在tty_driver的tty_port数组里对用下表找到tty_port挂载在tty_struct.tty_port

    总结:用户层总是与tty_struct结构体打交道。最后都会调用到tty_driver-->ops里,主要又客户自己实现

     

    三、代码梳理

    1. serial模块

    static int __init xuartps_init(void)
    {
    	int retval = 0;
    
    	/* Register the xuartps driver with the serial core */
    	retval = uart_register_driver(&xuartps_uart_driver);-------》注册tty_driver
    	if (retval)
    		return retval;
    
    	/* Register the platform driver */
    	retval = platform_driver_register(&xuartps_platform_driver);---->注册tty_port
    	if (retval)
    		uart_unregister_driver(&xuartps_uart_driver);
    
    	return retval;
    }
    int uart_register_driver(struct uart_driver *drv)
    {
        struct tty_driver *normal;
        drv->tty_driver = normal;
    
    	normal->driver_name	= drv->driver_name;
    	normal->name		= drv->dev_name;
    	normal->major		= drv->major;
    	normal->minor_start	= drv->minor;
    	normal->type		= TTY_DRIVER_TYPE_SERIAL;
    	normal->subtype		= SERIAL_TYPE_NORMAL;
    	normal->init_termios	= tty_std_termios;
    	normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
    	normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600;
    	normal->flags		= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
    	normal->driver_state    = drv;
    	tty_set_operations(normal, &uart_ops);--------->ops需要用户侧实现
    
        	for (i = 0; i < drv->nr; i++) {
    		struct uart_state *state = drv->state + i;
    		struct tty_port *port = &state->port;
    
    		tty_port_init(port);
    		port->ops = &uart_port_ops;--------》需要用户侧实现,该处只是分别tty_port数组,挂载 
                                                    tty_driver上,后续将具体的填充
    		port->close_delay     = HZ / 2;	/* .5 seconds */
    		port->closing_wait    = 30 * HZ;/* 30 seconds */
    	}
    
        retval = tty_register_driver(normal);

    红色圈里为注册tty_driver实现:生成cdev[]数组,tty_struct[], tty_port[] ,后续注册会填充该数组。 

    static int xuartps_probe(struct platform_device *pdev)
    {
        port = xuartps_get_port();---------》通过设备树,找到id.具体参考链接文档。
        rc = uart_add_one_port(&xuartps_uart_driver, port);----》xuartps_uart_driver 提前注册
    }
    
    int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
    {
        	tty_dev = tty_port_register_device_attr(port, drv->tty_driver,
    			uport->line, uport->dev, port, tty_dev_attr_groups);
    }
    
    struct device *tty_port_register_device_attr(struct tty_port *port,
    		struct tty_driver *driver, unsigned index,
    		struct device *device, void *drvdata,
    		const struct attribute_group **attr_grp)
    {
    	tty_port_link_device(port, driver, index);-----》将port放在tty_port数组里
    	return tty_register_device_attr(driver, index, device, drvdata,----》创建设备文件
    			attr_grp);
    }

     

    static const struct tty_operations uart_ops = {
    	.open		= uart_open,
    	.close		= uart_close,
    	.write		= uart_write,
    	.put_char	= uart_put_char,
    	.flush_chars	= uart_flush_chars,
    	.write_room	= uart_write_room,
    	.chars_in_buffer= uart_chars_in_buffer,
    	.flush_buffer	= uart_flush_buffer,
    	.ioctl		= uart_ioctl,
    	.throttle	= uart_throttle,
    	.unthrottle	= uart_unthrottle,
    .....
    }
    
    static int uart_write(struct tty_struct *tty,
    					const unsigned char *buf, int count)
    {
        circ = &state->xmit; ------->用户自己定义的buf
        	while (1) {
    		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
    		if (count < c)
    			c = count;
    		if (c <= 0)
    			break;
    		memcpy(circ->buf + circ->head, buf, c);拷贝buf
    		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
    		buf += c;
    		count -= c;
    		ret += c;
    	}
    
        uart_start(tty);-------》启动发送中断
    }

     

    2. sdio_uart

    static int __init sdio_uart_init(void)
    {
        sdio_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR);
        
        tty_drv->driver_name = "sdio_uart";
    	tty_drv->name =   "ttySDIO";
    	tty_drv->major = 0;  /* dynamically allocated */
    	tty_drv->minor_start = 0;
    	tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
    	tty_drv->subtype = SERIAL_TYPE_NORMAL;
    	tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
    	tty_drv->init_termios = tty_std_termios;
    	tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;
    	tty_drv->init_termios.c_ispeed = 4800;
    	tty_drv->init_termios.c_ospeed = 4800;
    	tty_set_operations(tty_drv, &sdio_uart_ops);------->自己实现
        
        ret = tty_register_driver(tty_drv);
    
        ret = sdio_register_driver(&sdio_uart_driver);-------》注册tty_port
    }

     

    static int sdio_uart_probe(struct sdio_func *func,
    			   const struct sdio_device_id *id)
    {
        tty_port_init(&port->port);
        port->port.ops = &sdio_uart_port_ops; //用户自己实现
        
        ret = sdio_uart_add_port(port); //放到自己定义的数组里,后续通过port找到sdio_port
    
        dev = tty_port_register_device(&port->port, 注册
    				sdio_uart_tty_driver, port->index, &func->dev);
    }

     

    static const struct tty_operations sdio_uart_ops = {
    	.open			= sdio_uart_open,
    	.close			= sdio_uart_close,
    	.write			= sdio_uart_write,
    	.write_room		= sdio_uart_write_room,
    	.chars_in_buffer	= sdio_uart_chars_in_buffer,
    	.send_xchar		= sdio_uart_send_xchar,
    }
    
    static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf,
    			   int count)
    {
        struct sdio_uart_port *port = tty->driver_data;
    	int ret;
    
    	if (!port->func)
    		return -ENODEV;
    
        //拷贝到机子定义的fifo里
    	ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock);
    	if (!(port->ier & UART_IER_THRI)) {
    		int err = sdio_uart_claim_func(port);
    		if (!err) {
    			sdio_uart_start_tx(port);
    			sdio_uart_irq(port->func);
    			sdio_uart_release_func(port);
    		} else
    			ret = err;
    	}
    
    	return ret;
    }

     

    3. usb_serial

     

    以ch341为例说明:

    1. seria_bus的注册

    static int __init usb_serial_init(void)
    {
        usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS);
        
        result = bus_register(&usb_serial_bus_type);---------》usb_serial_bus 总线注册
    
        usb_serial_tty_driver->driver_name = "usbserial";
    	usb_serial_tty_driver->name = "ttyUSB";
    	usb_serial_tty_driver->major = SERIAL_TTY_MAJOR;
    	usb_serial_tty_driver->minor_start = 0;
    	usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
    	usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
    	usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW |
    						TTY_DRIVER_DYNAMIC_DEV;
    	usb_serial_tty_driver->init_termios = tty_std_termios;
    	usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD
    							| HUPCL | CLOCAL;
    	usb_serial_tty_driver->init_termios.c_ispeed = 9600;
    	usb_serial_tty_driver->init_termios.c_ospeed = 9600;
    	tty_set_operations(usb_serial_tty_driver, &serial_ops);
    	result = tty_register_driver(usb_serial_tty_driver);   //tty_driver注册
    	if (result) {
    		pr_err("%s - tty_register_driver failed\n", __func__);
    		goto exit_reg_driver;
    	}
    
    	/* register the USB driver */
    	result = usb_register(&usb_serial_driver); //图中:drv1注册
    	if (result < 0) {
    		pr_err("%s - usb_register failed\n", __func__);
    		goto exit_tty;
    	}
    
    }
    
    

     

    // drv注册
    static struct usb_serial_driver * const serial_drivers[] = {
    	&ch341_device, NULL
    };
    
    module_usb_serial_driver(serial_drivers, id_table);-------》
    
    int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
    				const char *name,
    				const struct usb_device_id *id_table)
    {
        struct usb_driver *udriver;
        //usb_drv注册
    	rc = usb_register(udriver); usb_drv注册, 自己注册一个driver
    	if (rc)
    		return rc;
        udriver->probe = usb_serial_probe;  --------------》probe
    
    	for (sd = serial_drivers; *sd; ++sd) {
    		(*sd)->usb_driver = udriver;
    		rc = usb_serial_register(*sd);  ---------》usb_serial_drv注册
    		if (rc)
    			goto failed;
    	}
    }
    
    //usb_serial_drv注册
    static int usb_serial_register(struct usb_serial_driver *driver)
    {    
        retval = usb_serial_bus_register(driver);
    }
    
    //dev注册
    1. 这对usb_dev 是platform产生,匹配usb_driver
    static int usb_serial_probe(struct usb_interface *interface,
    			       const struct usb_device_id *id)
    {
    
        struct usb_serial_port *port;
    
        	for (i = 0; i < max_endpoints; ++i) {
    		port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
    		if (!port)
    			goto probe_error;
    		tty_port_init(&port->port);
    		port->port.ops = &serial_port_ops;
    		port->serial = serial;
    		spin_lock_init(&port->lock);
    		/* Keep this for private driver use for the moment but
    		   should probably go away */
    		INIT_WORK(&port->work, usb_serial_port_work);
    		serial->port[i] = port;
    		port->dev.parent = &interface->dev;
    		port->dev.driver = NULL;
    		port->dev.bus = &usb_serial_bus_type; --------->bus
    		port->dev.release = &usb_serial_port_release;
    		device_initialize(&port->dev);
    	}
        ,,,,,,
        retval = device_add(&port->dev);
        //后续进行probe  ,借用bus的probe,而不是在drv的probe
    }
    // bus probe
    static int usb_serial_device_probe(struct device *dev)
    {
        tty_register_device(usb_serial_tty_driver, minor, dev); //tty_por注册
    }

     

    展开全文
  • from losing its controlling tty. I thought of overcoming this problem by having the runtime gain control of the tty once the shim has ended. But if the runtime is sent a SIGKILL in standalone, the ...
  • tty相关

    2019-09-27 17:35:47
    tty相关 ttyn:虚拟终端,有tty1-tty6 终端设备的统称 tty0:虚拟终端的别名 tty:控制终端,表示当前tty设备。登陆的控制终端为tty,映射到实际的虚拟终端设备。如tty1、tty2等。 在命令行模式下,是映射到虚拟终端...
  • TTY设备

    2018-09-16 16:18:43
    一、TTY设备 在*nix中,tty设备用来抽象串口类型的设备,它位于字符驱动之下,抽象了串口设备需要的特性、功能,抽象后的一个tty设备即可表示一个串行输入、输出接口(比如控制台口,串口、pty设备接口)。 TTY的...
  • <div><p>One common problem when accessing the TTY is that you cannot access it as regular user. The expected behavior is that the TTY terminal application errors this out to the user. TIO is simply ...
  • tty_driver

    2016-04-06 14:44:38
    linux tty driver

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,984
精华内容 7,193
热门标签
关键字:

tty