tty驱动初步了解学习

这篇具有很好参考价值的文章主要介绍了tty驱动初步了解学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、linux tty驱动框架

本人是linux驱动初学者,最近在初步学习uart驱动,在这记录下来自己的理解
linux3.10
soc:君正x1000e

四位大佬写的很好
https://blog.csdn.net/cosmoslhf/article/details/16945009
https://blog.csdn.net/lizuobin2/article/details/51801183
https://blog.csdn.net/Luckiers/article/details/123577836
https://blog.csdn.net/mike8825/article/details/107598833

在Linux kernel中,tty驱动不像于spi,iic等那么架构简单,它是一个庞大的系统,它的框架大体如下图一。我们作为普通的驱动开发移植人员,不会从零写tty驱动,一般都是厂家根据现有的tty驱动和自家芯片修改,拿到板子按照厂家的配置,串口应该使能直接使用的。但是开发的过程中也有可能需要用到串口,一般会修改serial驱动,这样我们不会动tty_core层。

Linux tty子系统包含:tty核心(tty_core),tty线路规程(tty_line_discipine)和tty驱动(tty_driver)。tty核心是对整个tty设备的抽象,对用户提供统一的接口,tty线路规程是对传输数据的格式化,tty驱动则是面向tty设备的硬件驱动。
图一tty驱动初步了解学习

二、uart驱动数据架构

1、主要用到的数据架构图二

图二
tty驱动初步了解学习
uart_driver描述uart设备,其他下面有2个重要的结构体uart_state(用于描述底层硬件信息),tty_drvier(tty层驱动)。
uart_driver结构体

struct uart_driver {
   
	struct module		*owner;
	const char		*driver_name;//串口驱动名字
	const char		*dev_name;//设备名字
	int			 major;
	int			 minor;
	int			 nr;
	struct console		*cons;

	/*
		有两个成员未被赋值,对于tty_driver 代表的是上层,它会在 register_uart_driver 中的过程中赋值,
		而uart_state 则代表下层,uart_state 也会在register_uart_driver 的过程中分配空间,
		但是它里面真正设置硬件相关的东西是 uart_state->uart_port ,
		这个uart_port 是需要我们从其它地方调用 uart_add_one_port 来添加的。

	 */
	struct uart_state	*state;//底层指定硬件参数
	struct tty_driver	*tty_driver;//tty层
};

一般来说一个芯片具有多个串口,比如君正x1000e具有3个串口,那uart_state应该有多个,每个保存一个串口信息。
tty_prot是TTY device的一种抽象

circ_buf是一个发送缓存,在写数据时,当tty层调用驱动提供的写函数时,数据会首先进入circ_buf的环形缓存区,然后由uart_port从缓存区中取数据,将其写入到串口设备中。
当uart_port从串口设备接收到数据时,它会直接将数据放入tty的缓存中(tty缓存属于tty_port),进而放入对应的line discipline的缓存区中。
tty驱动初步了解学习
uart_state结构体
uart_state中最重要的结构体成员uart_port
uart_state->uart_port(在这保存硬件串口信息)

truct uart_port {
   
	spinlock_t		lock;			/* port lock */
	unsigned long		iobase;			/* io基地址 */
	unsigned char __iomem	*membase;		/*内存基地址 */
	unsigned int		(*serial_in)(struct uart_port *, int);//串口接受函数指针
	void			(*serial_out)(struct uart_port *, int, int);//串口发送函数指针
	void			(*set_termios)(struct uart_port *,
				               struct ktermios *new,
				               struct ktermios *old);
	int			(*handle_irq)(struct uart_port *);
	void			(*pm)(struct uart_port *, unsigned int state,
				      unsigned int old);
	void			(*handle_break)(struct uart_port *);
	unsigned int		irq;			/* irq number */
	unsigned long		irqflags;		/* irq flags  */
	unsigned int		uartclk;		/* base uart clock */
	unsigned int		fifosize;		/* tx fifo size */
	unsigned char		x_char;			/* xon/xoff char */
	unsigned char		regshift;		/* reg offset shift */
	unsigned char		iotype;			/* io访问方式 */
	unsigned char		unused1;
....
	unsigned int		mctrl;			/* 当前控制模式*/
	unsigned int		timeout;		/* character-based timeout */
	unsigned int		type;			/* port type */
	const struct uart_ops	*ops;
	unsigned int		custom_divisor;
	unsigned int		line;			/* port index */
	resource_size_t		mapbase;		/* for ioremap */
	struct device		*dev;			/* parent device */
	unsigned char		hub6;			/* this should be in the 8250 driver */
	unsigned char		suspended;
	unsigned char		irq_wake;
	unsigned char		unused[2];
	void			*private_data;		/* generic platform data pointer */
};

tty_port结构体
保存着tty层驱动信息


struct tty_driver {
   
	int	magic;		/* magic number for this structure */
	struct kref kref;	/* Reference management */
	struct cdev *cdevs;
	struct module	*owner;
	const char	*driver_name;
	const char	*name;
	int	name_base;	/* offset of printed name */
	int	major;		/* major device number */
	int	minor_start;	/* start of minor device number */
	unsigned int	num;	/* number of devices allocated */
	short	type;		/* type of tty driver */
	short	subtype;	/* subtype of tty driver */
	struct ktermios init_termios; /* Initial termios */
	unsigned long	flags;		/* tty driver flags */
	struct proc_dir_entry *proc_entry; /* /proc fs entry */
	struct tty_driver *other; /* only used for the PTY driver */

	/*
	 * Pointer to the tty data structures
	 */
	struct tty_struct **ttys;
	struct tty_port **ports;
	struct ktermios **termios;
	void *driver_state;

	/*
	 * Driver methods
	 */

	const struct tty_operations *ops;
	struct list_head tty_drivers;
};

三、uart驱动编写步骤

uart它是linux在tty的基础上又做了一层封装,得益于该封装层,可以比较容易的编写新的串口驱动程序。
只需要2大步
(1)uart_register_driver函数注册一个串口设备
(2)platform_driver_register注册一个平台设备(最后执行uart_add_one_port)

驱动大概框架文章来源地址https://www.toymoban.com/news/detail-402778.html


static int serial_jz47xx_startup(struct uart_port *port)
{
   
	/*request_irq注册驱动*/
	retval = request_irq(up->port.irq, serial_jz47xx_irq, 0, up->name, up);//request irq
	if (retval)
		return retval;

	/*清理寄存器*/

	/*初始化串口*/

	/*使能中断*/
}
/*操作集合*/
struct uart_ops serial_jz47xx_pops = {
   
	/*回调函数*/
	.startup	= serial_jz47xx_startup,//start endport
	....
};

static struct uart_driver serial_jz47xx_reg = {
   
	.owner		= THIS_MODULE,		
	.driver_name	= "JZ47XX serial",  //串口驱动名字
	.dev_name	= "ttyS",     //串口设备名字
	.major		= TTY_MAJOR,    //主设备号
	.minor		= 64,
	.nr		= PORT_NR,/* 该uart_driver支持的串口个数(最大) */
	.cons		= JZ47XX_CONSOLE,	/* 其对应的console.若该uart_driver支持serial console,否则为NULL */
};


static int 

到了这里,关于tty驱动初步了解学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Elasticsearch初步了解学习记录

    目录 前言 一、ElasticSearch是什么? 二、使用步骤(python版) 1.引入包 2.连接数据库 3.创建索引 4.写入数据 5.查询数据 三、相关工具介绍 1.ES浏览器插件 总结 随着数据量的不断增加,传统的查询检索在速度上遇到了瓶颈,这个时候就需要一个更具性能的技术来支持大数据量的

    2024年04月16日
    浏览(37)
  • 初步了解ES适合新手逐步学习

    1.1 准备数据 1.2 match和term 做查询,返回的结果会给每一个文档做一个相关性算分,用_score来表示,如果一个查询匹配到多条数据,那么_score最高的会排在最前面,表示匹配度最高。这个算分的过程其实是比较消耗性能的,如果我们不关注这个属性的话,可以通过Filter的方式绕

    2024年02月08日
    浏览(45)
  • tty(四)tty框架分析

    基于linux-3.14.16 重要文件:tty_io.c 开机添加了2个次设备号为0和1的字符设备,即/dev/tty和/dev/console。 最终调用的__tty_alloc_driver分配 先分配一个tty_driver 因为flags为0,所以将会分配指定lines数量的ttys,termios,ports,并且cdevs将会用lines赋值,cdevs也将分配lines个。 获取设备号,指

    2024年02月12日
    浏览(30)
  • 通识强化学习,初步了解强化学习的运行规则和估值方法

    目录 1.强化学习的发展及应用现状 1.1.强化学习的由来 1.2.强化学习的应用 2.强化学习的基本概念 2.1.概要介绍 2.2.强化学习的构成要素 2.3.工作过程 2.4.强化学习的主要特点 2.5.与其他机器学习方法的区别 3.估值方法 3.1.估值的方式 3.2.依据更新方式 目前,大家认为强化学习(

    2024年02月16日
    浏览(43)
  • PCIE学习系列 五(Linux之PCIe设备驱动开发框架)

    本文讲述一个开源的PCIe设备驱动,通过这个例子可以基本上理解所有的PCIe设备驱动。后续也会做关于Linux各类驱动的文章。 通过前面的学习,我们知道PCIe设备访问之前需要先做枚举。一般来说,PCI设备的枚举操作不需要我们来做,BIOS或者系统初始化时已经做好了,当系统枚

    2024年02月05日
    浏览(58)
  • 爬虫——Scrapy框架 (初步学习+简单案例)

    目录 1.scrapy基本用途: 2.结构: 3.scrapy文件结构(示例:game) 4.scrapy安装 二、 简单实例 1.创建项目(打开命令窗口) 2.打开项目  一、Scrapy框架 1.scrapy基本用途: Scrapy是一个快速、高效率的网络爬虫框架,用于抓取web站点并从页面中提取结构化的数据。 Scrapy被广泛用于数据

    2024年02月12日
    浏览(50)
  • docker 学习--03 环境安装(本人使用的win10 Linux也是在win10下模拟)

    docker 学习-- 01 基础知识 docker 学习-- 02 常用命令 docker 学习-- 03 环境安装 docker 学习-- 04 实践 1(宝塔) docker 学习-- 04 实践 2 (lnpmr环境) `` 在 Windows 10 上安装 Docker 分为两种方式:使用 Docker Desktop for Windows 和安装 Docker 工具包。 这里使用的是 Docker Desktop for Windows Docker Deskt

    2024年02月12日
    浏览(36)
  • 【JavaEE】JavaEE进阶:框架的学习 - Spring的初步认识

    JavaEE进阶首章 在之前的学习中,我们已经掌握了Servlet的框架去完成一个项目,而目前企业正在使用的技术则是我们接下来重点学习的! 本文章为 JavaEE进阶的第一篇文章,JavaEE进阶我们将学习: Spring全家桶 Spring / Spring Boot/ Spring MVC ,Spring Cloud为社招必须,校招不须 MyBatis

    2024年02月17日
    浏览(41)
  • 初步了解STM32的学习笔记(以STM32F103C8T6为例)

      STM32F103C8T6属于主流系列STM32F1 内核是ARM Cortex-Mex3 主频为72Hz RAM:20K(SRAM) ROM:64K(Flash) 封装:LQFP48 供电:2~3.6V(一般为3.3) (注意:以前51用的是5V,而USB也是5V,所以直接插上,而stm32会加上一个稳压芯片,让电压为3.3V) (所有图都是用的是B站上整理过的)  表里面

    2024年02月05日
    浏览(47)
  • linux内核网络驱动框架(linux驱动开发篇)

    网络驱动的核心: 1、就是初始化 net_device 结构体中的各个成员变量, 2、然后将初始化完成以后的 net_device 注册到 Linux 内核中 1、网络设备(用net_device结构体) 2、网络设备的操作集( net_device_ops结构体 ) 3、sk_buff结构体 网络是分层的,对于应用层而言不用关系具体的底层是

    2023年04月08日
    浏览(80)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包