tty设备驱动程序设计

设备驱动中的tty(kernel-4.7) TTY概念解析在Linux系统中,终端是一类字符型设备,它包括多种类型,通常使用tty来简称各种类型的终端设备。• 串口终端(/dev/ttyS*) 串口终端是使用计算机串口连接的终端设备。Linux把每个串行端口都看作是一个字符设备。这些串行端口所对应的设备名称是 /dev/ttySAC0;/dev/ttySAC1……• 控制台终端(/dev/console) 在Linux系统中,计算机的 阅读详情

1. linux内核中,tty层次结构包括了:

a. tty 核心

b. tty 线路规程(discipline): 以协议转换的方式,格式化从一个用户或硬件收到的数据, 如PPP协议或蓝牙协议。

c. tty驱动

三层之间数据流通关系如下图所示:


tty设备发送数据流程: tty核心从用户获取想要发送给一个tty设备的数据,tty核心将数据传递给tty线路规程驱动,然后数据被传递到tty驱动,tty驱动将数据转换为可以发送给硬件的格式。

tty设备接收数据流程: 从硬件接收到的数据向上交给tty驱动,然后进入tty线路规程,再进入tty核心,在这里被一个用户获取。

尽管大多数时候tty核心和tty之间的数据传输会经历tty线路规程的转换,但是tty驱动与tty核心之间也可以直接传输数据。

2. tty_driver 和 tty_operation 结构体:

tty设备驱动的主要工作是填充tty_driver结构体中的成员,实现tty_operations结构体中的成员函数。

struct tty_driver {
    int    magic;        /* magic number for this structure */ //在alloc_tty_driver()函数中被初始化
    struct kref kref;    /* Reference management */
    struct cdev cdev;    //对应字符设备的cdev
    struct module    *owner;     //这个驱动模块的拥有者
    const char    *driver_name;   //驱动名,在/proc/tty 和 /sysfs 中使用 
    const char    *name;     //设备名,在 /dev 下使用,即驱动的设备节点名,如:ttySn
    int    name_base;    /* offset of printed name */ //为创建设备名字而使用的开始编号,在内核创建一个tty设备名称时使用。
    int    major;        /* major device number */ //驱动程序的主设备号
    int    minor_start;    /* start of minor device number */ //最小次设备号,通常与 name_base 值相同,经常为0.
    int    minor_num;    /* number of *possible* devices */ //此设备号的个数,也就是拥有相同驱动的设备的个数
    int    num;        /* number of devices allocated */ //同minor_num.
    short    type;        /* type of tty driver */
    short    subtype;    /* subtype of tty driver */
    struct ktermios init_termios; /* Initial termios */ //初始线路规程设置,用来提供一个线路(line)设置集合。
    int    flags;        /* tty driver flags */
    struct proc_dir_entry *proc_entry; /* /proc fs entry */ //proc入口结构体,如果驱动程序实现write_proc()或read_proc(),它将由tty 核心创建。
    struct tty_driver *other; /* only used for the PTY driver */ //指向tty从属设备驱动程序的指针,只能被pty驱动程序使用。

    /*
     * Pointer to the tty data structures
     */
    struct tty_struct **ttys;
    struct ktermios **termios;
    struct ktermios **termios_locked;
    void *driver_state;   //tty 驱动程序内部的状态,也只能被 pty 驱动程序使用。

    /*
     * Driver methods
     */
    const struct tty_operations *ops;
    struct list_head tty_drivers; //构成一个 tty 驱动程序链表。把所有不同的tty驱动程序连接起来。
};

--- type :

--- subtype :

描述 tty 驱动程序的类型,subtype 取决于 type. type 可以有以下几种类型:

TTY_DRIVER_TYPE_SYSTEM --- 在tty子系统内部使用,表明tty子系统正在处理一个内部的tty驱动程序。这种类型不能被常规的tty驱动程序使用

    subtype 值可以是:SYSTEM_TYPE_TTY, SYSTEM_TYPE_CONSOLE, SYSTEM_TYPE_SYSCONS, SYSTEM_TYPE_SYSPTMX

TTY_DRIVER_TYPE_CONSOLE --- 只被控制台驱动程序使用,CONSOLE.

TTY_DRIVER_TYPE_SERIAL --- 可以被任何串行类驱动程序使用。这是type最常用的设置之一。

   subtype 值可以为:SERIAL_TYPE_NORMAL, SERIAL_TYPE_CALLOUT,这取决于驱动程序的类型。

TTY_DRIVER_TYPE_PTY --- 伪终端接口(pty)使用。

   subtype值可以为:PTY_TYPE_MASTER, PTY_TYPE_SLAVE.

--- flags  :  tty驱动和 tty 核心都使用flags 来表明当前驱动程序的状态及该tty驱动程序的类型,可以是:

TTY_DRIVER_RESET_TERMIOS --- 该标志表示当最后一个进程关闭该设备时, tty 核心对 termios 复位。

   这对控制台和pty驱动程序非常有用。比如一个用户将终端设置为非常规状态,如果设置了该位,当用户退出时,或控制该会话进程关闭时,终端能自动恢复常规值。

TTY_DRIVER_REAL_RAW --- 该标志表示驱动程序使用奇偶校验或中断字符线路规程。

   这使得线路规程能比较快的方式接收字符,所有的tty驱动程序通常都设该位。

TTY_DRIVER_NO_DEVFS --- 该位表示 当tty_register_driver()时,tty核心不需要为tty驱动程序创建任何的 devfs 入口。

    这对于那些需要动态创建和删除次设备的驱动程序来说非常有用,比如:USB转串口驱动程序,USB调制解调器驱动程序,USB蓝牙tty驱动程序

TTY_DRIVER_INSTALLED --- 它由tty核心控制, 当tty驱动程序注册后,tty核心置该位,而不是tty驱动程序。

--- init_termios : 初始线路设置,也是termios结构体

--- termios :当前的线路设置,线路设置控制当前的波特率,数据大小,流控制等参数。

struct tty_operations {
    struct tty_struct * (*lookup)(struct tty_driver *driver,
            struct inode *inode, int idx);
    int (*install)(struct tty_driver *driver, struct tty_struct *tty);
    void (*remove)(struct tty_driver *driver, struct tty_struct *tty);
    int (*open)(struct tty_struct * tty, struct file * filp);
    void (*close)(struct tty_struct * tty, struct file * filp);
    void (*shutdown)(struct tty_struct *tty);
    void (*cleanup)(struct tty_struct *tty);
    int (*write)(struct tty_struct * tty,
         const unsigned char *buf, int count);
    int (*put_char)(struct tty_struct *tty, unsigned char ch);//单个字节写函数,把单个字节写入设备。
    void (*flush_chars)(struct tty_struct *tty);  //与wait_until_sent()一样,刷新数据到硬件。
    int (*write_room)(struct tty_struct *tty);   //表示有多少缓冲区空闲,
    int (*chars_in_buffer)(struct tty_struct *tty);  //缓冲区长度
    int (*ioctl)(struct tty_struct *tty, struct file * file,
         unsigned int cmd, unsigned long arg);
    long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
             unsigned int cmd, unsigned long arg);
    void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
    void (*throttle)(struct tty_struct * tty);   //用于控制tty核心输入缓存,当tty核心输入缓存满时,throttle()函数将被调用,tty驱动试图通知设备不该发送字符给它了。
    void (*unthrottle)(struct tty_struct * tty); //当tty核心输入缓冲被清空后,unthrottle()函数被调用,暗示设备可以接受数据了,
    void (*stop)(struct tty_struct *tty);
    void (*start)(struct tty_struct *tty);
//stop()和start(),跟throttle()和unthrottle()类似,他们表示tty驱动应该停止发送数据给设备,和恢复发送数据给设备。
    void (*hangup)(struct tty_struct *tty); //tty驱动挂起tty设备,在此函数中进行相关的硬件操作。
    int (*break_ctl)(struct tty_struct *tty, int state);  //线路中断控制函数被调用
    void (*flush_buffer)(struct tty_struct *tty);   //用于刷新缓冲区,并丢弃任何剩下的数据。
    void (*set_ldisc)(struct tty_struct *tty);      //设置线路规程,当tty核心改变tty驱动的线路规程时,这个函数被调用。
    void (*wait_until_sent)(struct tty_struct *tty, int timeout);
    void (*send_xchar)(struct tty_struct *tty, char ch);   //X-类型字符发送函数。
    int (*tiocmget)(struct tty_struct *tty, struct file *file);   //获取tty设备的线路设置
    int (*tiocmset)(struct tty_struct *tty, struct file *file,    //设置tty设备的线路设置, 参数set和clear包含了要设置或清除的线路设置。
            unsigned int set, unsigned int clear);
    int (*resize)(struct tty_struct *tty, struct winsize *ws);
    int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew); //当设备的termios设置被改变时,set_termios()函数被tty核心调用。
    int (*get_icount)(struct tty_struct *tty,
                struct serial_icounter_struct *icount);
#ifdef CONFIG_CONSOLE_POLL
    int (*poll_init)(struct tty_driver *driver, int line, char *options);
    int (*poll_get_char)(struct tty_driver *driver, int line);
    void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
#endif
    const struct file_operations *proc_fops;
};

3.
termios 结构体:

用来描述当前线路设置,这些线路设置控制当前波特率,数据大小,数据流控制 等。

typedef unsigned char    cc_t;
typedef unsigned int    speed_t;
typedef unsigned int    tcflag_t;

#define NCCS 19
struct termios {
    tcflag_t c_iflag;        /* input mode flags */  //输入模式标志
    tcflag_t c_oflag;        /* output mode flags */  //输出模式标志
    tcflag_t c_cflag;        /* control mode flags */ //控制模式标志
    tcflag_t c_lflag;        /* local mode flags */   //本地模式标志
    cc_t c_line;            /* line discipline */     //线路规程类型
    cc_t c_cc[NCCS];        /* control characters */  //控制字符数组
};

struct termios2 {
    tcflag_t c_iflag;        /* input mode flags */
    tcflag_t c_oflag;        /* output mode flags */
    tcflag_t c_cflag;        /* control mode flags */
    tcflag_t c_lflag;        /* local mode flags */
    cc_t c_line;            /* line discipline */
    cc_t c_cc[NCCS];        /* control characters */
    speed_t c_ispeed;        /* input speed */
    speed_t c_ospeed;        /* output speed */
};

struct ktermios {
    tcflag_t c_iflag;        /* input mode flags */
    tcflag_t c_oflag;        /* output mode flags */
    tcflag_t c_cflag;        /* control mode flags */
    tcflag_t c_lflag;        /* local mode flags */
    cc_t c_line;            /* line discipline */
    cc_t c_cc[NCCS];        /* control characters */
    speed_t c_ispeed;        /* input speed */
    speed_t c_ospeed;        /* output speed */
};
驱动会用一个标准的数值集初始化这个成员,这个数值集源于tty_std_termios变量:

struct ktermios tty_std_termios = {    /* for the benefit of tty drivers */
    .c_iflag = ICRNL | IXON,  //输入模式
    .c_oflag = OPOST | ONLCR,  //输出模式
    .c_cflag = B38400 | CS8 | CREAD | HUPCL,   //控制模式
    .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |   
         ECHOCTL | ECHOKE | IEXTEN,  //本地模式
    .c_cc = INIT_C_CC,               //控制字符,用来修改终端的特殊字符映射。
    .c_ispeed = 38400,
    .c_ospeed = 38400
};

EXPORT_SYMBOL(tty_std_termios); 

4. Linux内核提供了一组操作 tty_driver 和 tty设备的函数:

4.1 struct tty_driver alloc_tty_driver(int lines);  ---分配tty驱动

该函数返回 tty_driver指针,

参数lines 是要分配的设备数量,lines会被赋值给tty_driver的num成员。

magic 成员会在这里赋值,如TTY_DRIVER_MAGIC。

定义如下:

struct tty_driver *alloc_tty_driver(int lines)
{
	struct tty_driver *driver;

	driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
	if (driver) {
		kref_init(&driver->kref);
		driver->magic = TTY_DRIVER_MAGIC;
		driver->num = lines;
		/* later we'll move allocation of tables here */
	}
	return driver;
}
EXPORT_SYMBOL(alloc_tty_driver);
使用例子:

xxx_tty_driver = alloc_tty_driver(XXX_TTY_MINORS);
if(!xxx_tty_driver)    //分配失败
    return -ENOMEM;

4.2 int tty_register_driver(struct tty_driver *driver); --- 注册tty驱动

成功时返回0,参数为 由 alloc_tty_driver()分配的 tty_driver 指针。

定义如下:

  1. /*
     * 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;
        struct device *d;
    
        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;    //tty_struct 赋值
            driver->termios = (struct ktermios **)(p + driver->num); // 设置线路规程 tty_driver->termios
        } 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++) {
                d = tty_register_device(driver, i, NULL);
                if (IS_ERR(d)) {
                    error = PTR_ERR(d);
                    goto err;
                }
            }
        }
        proc_tty_register_driver(driver);    //procfs 注册
        driver->flags |= TTY_DRIVER_INSTALLED;  //完成后,flags 表示向tty core注册driver了。
        return 0;
    
    err:
        for (i--; i >= 0; i--)
            tty_unregister_device(driver, i);
    
        mutex_lock(&tty_mutex);
        list_del(&driver->tty_drivers);
        mutex_unlock(&tty_mutex);
    
        unregister_chrdev_region(dev, driver->num);
        driver->ttys = NULL;
        driver->termios = NULL;
        kfree(p);
        return error;
    }
    EXPORT_SYMBOL(tty_register_driver);
    
    例子:
    retval = tty_register_driver(xxx_tty_driver);
    if(retval) {
    	printk(KERN_ERR "failed to register tiny tty driver");
    	put_tty_driver(xxx_tty_driver); //减小tty_driver的引用计数
    	return retval;
    }
    int tty_unregister_driver(struct tty_driver *driver); --- 注销tty驱动;
    /*
     * Called by a tty driver to unregister itself.
     */
    int tty_unregister_driver(struct tty_driver *driver)
    {
    #if 0
        /* FIXME */
        if (driver->refcount)
            return -EBUSY;
    #endif
        unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
                    driver->num);
        mutex_lock(&tty_mutex);
        list_del(&driver->tty_drivers);
        mutex_unlock(&tty_mutex);
        return 0;
    }
    EXPORT_SYMBOL(tty_unregister_driver);
    

    4.3 void tty_register_device(struct tty_driver *driver, unsigned index, struct device *device); --- 注册tty设备
    仅有 tty_driver 是不够的,驱动必须依附于设备。

    index --- 设备的索引号
    定义如下:

    /**
     *    tty_register_device - register a tty device
     *    @driver: the tty driver that describes the tty device
     *    @index: the index in the tty driver for this tty device
     *    @device: a struct device that is associated with this tty device.
     *        This field is optional, if there is no known struct device
     *        for this tty device it can be set to NULL safely.
     *
     *    Returns a pointer to the struct device for this tty device
     *    (or ERR_PTR(-EFOO) on error).
     *
     *    This call is required to be made to register an individual tty device
     *    if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If
     *    that bit is not set, this function should not be called by a tty
     *    driver.
     *
     *    Locking: ??
     */
    struct device *tty_register_device(struct tty_driver *driver, unsigned index,
                     struct device *device)
    {
        char name[64];
        dev_t dev = MKDEV(driver->major, driver->minor_start) + index;
    
        if (index >= driver->num) {
            printk(KERN_ERR "Attempt to register invalid tty line number "
             " (%d).\n", index);
            return ERR_PTR(-EINVAL);
        }
    
        if (driver->type == TTY_DRIVER_TYPE_PTY)   //如果是pty设备,伪终端
            pty_line_name(driver, index, name);
        else
            tty_line_name(driver, index, name);
    
        return device_create(tty_class, device, dev, NULL, name); //在/sys/device下建立tty类
    }
    EXPORT_SYMBOL(tty_register_device);
    

    例子:

    for (i = 0; i < XXX_TTY_MINORS; ++i)
    	tty_register_device(xxx_tty_driver, i, NULL);
    void tty_unregister_device(struct tty_driver *driver, unsigned index);  --- 注销tty设备

    /**
     *     tty_unregister_device - unregister a tty device
     *     @driver: the tty driver that describes the tty device
     *     @index: the index in the tty driver for this tty device
     *
     *     If a tty device is registered with a call to tty_register_device() then
     *    this function must be called when the tty device is gone.
     *
     *    Locking: ??
     */
    
    void tty_unregister_device(struct tty_driver *driver, unsigned index)
    {
        device_destroy(tty_class,
            MKDEV(driver->major, driver->minor_start) + index);
    }
    EXPORT_SYMBOL(tty_unregister_device);
    

    例子:

    for (i = 0; i < XXX_TTY_MINORS; ++i)
    	tty_unregister_device(xxx_tty_driver, i);
    
     4.4  void tty_set_operations(struct tty_driver *driver, struct tty_operations *op);   --- 设置 tty 驱动操作函数:

    1. 该函数会把 tty_operaions 结构体中的函数指针,赋值到 tty_driver 对应的函数指针。
      在具体 tty 驱动中,通常会定义一个设备特定的 tty_operations。

    1. void tty_set_operations(struct tty_driver *driver,
                  const struct tty_operations *op)
      {
          driver->ops = op;
      };
      EXPORT_SYMBOL(tty_set_operations);
      
      

      终端设备驱动都围绕tty_driver结构体展开,一般应包含:
      1. 终端设备驱动模块加载和卸载函数:完成注册和注销tty_driver,初始化和释放终端设备对应的tty_driver结构体和硬件资源。
      2. 实现tty_operations结构体中的一系列成员:主要有open(),close(),write(),tiocmget(),tiocmset().


Windows上python的spark环境搭建 1.安装好JDK 下载并安装好jdk-12.0.1_windows-x64_bin.exe,配置环境变量: 新建系统变量JAVA_HOME,值为Java安装路径 新建系统变量CLASSPATH,值为 .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;(注意最前面的圆点) 配置系统变量PATH,添加 %JAVA_HOME%bin;%JAVA_HOME%jrebin 在CMD中输入:java或者java -version,不显示不是内部命令等,说明安装成功。 阅读详情

相关推荐

硬件笔记——HDMI接口

HDMI可以同时传输视频信号、音频信号和控制信号。其中高速信号有四组:从Data TX到Data RX有3组差分数据信号(TMDS_DATA0~2)和一组差分时钟信号(TMDS_CLOCK)。以及若干低速线。脚编号信号名称信号类型功能说明1热插拔检测连接状态检测。接收端通过此引脚向源端发送高电平信号,通知其已连接并可以开始读取EDID。2UTILITY车载用途悬空3TMDS数据通道2差分信号正极,用于传输视频像素、音频和数据包。4TMDS数据2屏蔽。

2501_94625908的博客 538

linux0.11 阅读笔记

---------------------------------------- linux0.11 阅读笔记 writer: hjjdebug date: 2019年 07月 30日 星期二 10:20:44 CST ---------------------------------------- 代码从以下网址获取: https://github.com/voidccc/linux0.11 ...

hjjdebug的专栏 462

什么!!!寒假就要准备暑期实习

介绍暑期实习,从作用,时间线,投递渠道,技术准备,常见问题,经验教训几个方面介绍暑期实习

今天不coding的博客 1725

TTY设备驱动结构

《TTY设备驱动结构》来自:刘建文 | 学术半·IT歌·文作者:刘建文关键字:Linux 驱动程序永久链接地址:http://arttech.us/y-2011/tty-device-driver.htmlpostmetaTags: Linux, 驱动程序译自:《Serial D

Kemin | 本博客独立到nakeman.cn 4618

【Windows Server 2019】活动目录 (Active Directory) ——理论

博文介绍了活动目录 (Active Directory) 的定义,作用以及与 DNS 的关系。同时也介绍了AD的组织结构,包括域控制器,子域,对象,属性,容器,组织单位,域间信任等术语的解释,实验拓扑图。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 7747

deepstream车道线检测自定义插件化,其中要注意pipeline的配置,如果插件位置配置不对,会报input format should be RGBA when using blur-obje

以上代码中,我们先从对象池中获取一个 DsUserMeta 对象,然后使用 get_lane_line_from_frame 函数获取车道线检测结果,并使用 add_lane_line_meta 函数将其添加到 DsUserMeta 对象中。注意,上述代码中的 get_lane_line_from_frame 函数和 add_lane_line_meta 函数需要你自己实现,用于从视频帧中提取车道线检测结果,并将其添加到 DsUserMeta 中。

pvmsmfchcs的博客 690

Linux TTY设备驱动程序原理

如何写TTY设备驱动程序可以参考Linux Device Driver的第18章和例子程序tiny_tty.c,这里主要分析驱动程序调用的kernel API后面的细节.驱动程序主要做3件事:struct tty_driver *alloc_tty_driver(int lines)int tty_register_driver(struct tty_driver *driver)

5322

大数据开发工程师必备面试题与解答

大数据开发岗位一直是互联网行业的热门方向,面试过程中既考察基础知识,也关注实际项目经验和问题解决能力。本文整理了等核心组件相关的高频面试题及参考解答,帮助大家高效准备面试。大数据面试不仅考察基础理论,更看重项目经验与问题解决能力。本文涵盖了等核心知识点及调优思路,希望能帮助你在面试中游刃有余。

X2829352498的博客 302

Linux TTY Driver

引用 蜗蜗科技 http://www.wowotech.net/tty_framework/435.html Linux终端和Line discipline图解 https://blog.youkuaiyun.com/dog250/article/details/78818612 一. TTY drive框图 二. TTY framework 2.1 框图 2.2 数据结构图 三. ...

vertor11的博客 1873

【NodeRed】node-red-contrib-opcua实现PLC读写

在之前的博文【Node-RED】node-red-contrib-opcua-server模块使用(1)中,我们介绍了用node-red-contrib-opcua-server模块实现OPCUA服务端的,以及二次开发的内容。本节博文中我们采用官方社区自带的node-red-contrib-opcua组件开展对OPCUA客户端的介绍,详细阐述用该组件中OpcUa-Client节点实现客户端对PLC的读写,以及实现过程中遇到的问题。由于官方社区中并没有找到该组件的介绍实例,这也是本博文编写的第1个原因。

weixin_48618536的博客 958

SOME/IP协议详解「4.1·经典AutoSAR下的SOME/IP架构」

SOME/IP协议详解「4.1·经典AutoSAR下的SOME/IP架构」 点击返回雪云飞星的SOME/IP协议详解「总目录」 SOME/IP协议详解「4.1·经典AutoSAR下的SOME/IP架构」1 CP的SOME/IP架构概览2 业务报文通信流3 服务发现通信和控制流 1 CP的SOME/IP架构概览 2 业务报文通信流 3 服务发现通信和控制流 点击返回雪云飞星的SOME/IP协议详解「总目录」 ...

雪云飞星的博客 6067

【转】linux2.6.28-tty设备驱动学习

linux2.6.28-tty设备驱动学习在Linux系统中,终端是一种字符设备,它有多种类型,通常使用tty来简称各种类型的终端设备。tty是Teletype的缩写,Teletype是最早出现的一种终端设备,很像电传打字机,是由Teletype公司产生的。Linux系统包含以下几类终端设备: 1、串行终端设备(/dev/ttySn).它是使用计算机串行端口连接的终端设备,也就是我们主板上

Linux Driver,Go! 2550

滑模观测器与锁相环结合应用:让电机“无感”也能精准旋转的奥秘

本文介绍了永磁同步电机无传感器控制中的滑模观测器(SMO)结合锁相环(PLL)技术。SMO通过创建虚拟电机模型,利用电流误差产生控制信号来估计反电动势;PLL则从反电动势中解码转子位置和速度信息。该组合方案兼具SMO的鲁棒性和PLL的高精度,计算量小且硬件要求低。文章详细阐述了原理、数学模型、参数整定方法及实际实现技巧,包括离散化处理、符号函数替代等优化手段,并分析了低速性能限制、抖振问题等常见挑战及解决方案。最后指出该技术未来将与人工智能、多观测器融合等方向结合发展。

汽车软件开发 195

从pty驱动学习tty设备驱动加载

本文从三个方向研究tty设备1、tty驱动的加载2、tty设备的打开3、tty设备的访问。

bruk_spp的博客 478

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Linux TTY设备驱动

tty设备有三层:tty核心、tty线路规程、tty驱动。我们写驱动只负责最底层的tty驱动,线路规程的设置也是在底层的tty驱动,tty核心是封装好的。用户空间主要是通过设备文件同tty核心交互,而tty核心根据用户空间的操作再选择跟tty线路规程或者tty驱动交互,例:设置硬件的ioctl指令就直接交给tty驱动处理,read和write操作交给tty线路规程处理。

墨染锦年的博客 691

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

tty驱动注册

文章是作为笔记,可能有的地方理解不对。 1、注册tty设备驱动 我们以cdc_acm.c为例来介绍tty设备驱动的注册流程 1.1、首先是注册tty驱动 static struct tty_driver *acm_tty_driver; acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS); acm_tty_driver-&gt;drive...

weixin_37303427的博客 1275

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

linux tty driver

Linux TTY 驱动 1.前言 上世纪,六七十年代,虽然已经有电脑了,但还没有普及,电脑还是极其昂贵的,普通老百姓都买不起这么贵的一台电脑。那时候,UNIX的发明人——汤普森,为了实现多用户能够同时登陆UNIX系统的目的,使用非常廉价的TTY设备连接电脑,通过TTY设备发送和接收来自UNIX系统的信息,实现系统连接多个TTY设备的功能,多个用户可以同时登陆UNIX系统。 Lin

尔华的博客 1189

如何用Go语言编写设备驱动:gopher-os控制台与TTY驱动开发实战

在操作系统开发中,设备驱动是连接硬件与内核的关键桥梁。本文将以gopher-os项目为例,带你深入了解如何用Go语言开发控制台与TTY设备驱动,掌握从接口设计到功能实现的完整流程。gopher-os作为一个用Go语言编写的操作系统内核原型,其设备驱动架构为我们提供了极佳的学习范例。 ## 驱动开发基础:理解TTY设备接口 TTY(Teletypewriter)设备是操作系统中处理终端输入输出的

gitblog_01108的博客 917

详解Linux的交互式命令行(Shell、TTY子系统、TTY设备、TTY名字的来历、TTY设备文件、几个特殊的TTY设备文件、终端的两个含义、被作为控制台的终端)

不过伪终端不像虚拟控制台终端那样系统启动后就存在并且一直运行,伪终端则需要人为打开才行,比如在Ubuntu图形界面下搜索Terminal打开,或者通过SSH远程连接打开。每个虚拟终端提供独立的会话,你可以在每个终端上执行不同的任务。Ubuntu图形界面下搜索Terminal打开的终端就是伪终端,另外通过网络远程连接(如 SSH)得到的终端也是伪终端,所以其实目前来说这种终端是很常用的。系统的输出(例如命令结果)会通过相应的终端设备文件返回给终端仿真程序,最终显示在终端窗口中。

昊虹AI笔记 1818

linux tty驱动实例

linux tty驱动实例

一叶知秋的博客 1828

对tty节点的操作tty_open

       接上一篇,我们已经注册了一个tty设备驱动并且在/dev生成相应的设备节点,我们对这个节点的操作open,read,write等对应的就是 static const struct file_operations tty_fops = { .llseek = no_llseek, .read = tty_read, .write = tty_write, .poll ...

weixin_37303427的博客 1197

Linux终端tty设备驱动

在Linux系统中,终端设备非常重要,没有终端设备,系统将无法向用户反馈信息,Linux中包含控制台、串口和伪终端3类终端设备。 14.1节阐述了终端设备的概念及分类,14.2节给 出了Linux终端设备驱动的框架结构,重点描述tty_driver结构体及其成员。14.3~14.5节在14.2节的基础上,分别给出了Linux 终端设备驱动模块加载/卸载函数和open()、close()函数,数据

titan_max的专栏 5761

linux tty

转自 https://www.cnblogs.com/hzl6255/p/9533327.html,很好的介绍tty的文章 1. TTY介绍 TTY(TeleType)指Linux中的一类终端(Terminal)设备, 是一种字符设备 在Linux中, tty可分为如下几类 串行端口终端(serial port terminal): 指使用计算机串行端口连接的终端设备, /dev/ttySn 伪终端(pseudo terminal): 通常是通过ssh登陆的终端, /dev/pts/* 控制终端(cont

weixin_44705391的博客 621

linux tty设备驱动,18.1. 一个小 TTY 驱动

## 18.1.一个小 TTY 驱动为解释 tty 核心如何工作, 我们创建一个小 tty 驱动, 可以被加载, 以及写入读出, 并且卸载. 任何一个 tty 驱动的主要数据结构是 struct tty_driver. 它用来注册和注销一个 tty 驱动到 tty 内核, 在内核头文件 中描述.为创建一个 struct tty_driver, 函数 alloc_tty_driver 必须用这个...

weixin_42325867的博客 524

sylixos下的tty设备

TTY概念 终端设备,又被称作 tty 设备。tty 一词源于 Teletypes,或者 teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘进行阅读和发送信息的媒介,后来被键盘与显示器取代,所以现在叫终端比较合适。终端是一种字符型设备,终端通常用于人机交互,比如我们启动系统后通过串口启动的一个 Shell 界面,就是一个串口终端。 SylixOS 中终端设备名称 在 S...

ScilogyHunter的博客 761

linux 设备驱动之tty 线路设置

linux 设备驱动之tty 线路设置

一叶知秋的博客 1306
上一篇: 终端设备类型
下一篇: 14_3_tty设备驱动
lamdoc
博客等级 码龄18年 155粉丝 655原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值