博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
串口驱动(二)
阅读量:3897 次
发布时间:2019-05-23

本文共 2870 字,大约阅读时间需要 9 分钟。

1. 注册tty的ldisc

        ldisc全称 line discipline(线路规程),因为历史原因,tty属于一类设备,而串口设备只是其中一种,所以该模块负责将用户操作桥接到不同的tty驱动。从代码上来看就是一个数组 tty_ldiscs[],比如串口驱动对于的线路规程是tty_ldiscs[0]。

//tty_io.c/* * Initialize the console device. This is called *early*, so * we can't necessarily depend on lots of kernel help here. * Just do some early initializations, and do the complex setup * later. */void __init console_init(void){	initcall_t *call;	/* Setup the default TTY line discipline. */	tty_ldisc_begin();	/*	 * set up the console device so that later boot sequences can	 * inform about problems etc..	 */	call = __con_initcall_start;	while (call < __con_initcall_end) {		(*call)();		call++;	}}//tty_ldisc.cvoid tty_ldisc_begin(void){	/* Setup the default TTY line discipline. */	(void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);}int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc){	tty_ldiscs[disc] = new_ldisc;   //即tty_ldiscs[N_TTY]=tty_ldisc_N_TTY	new_ldisc->num = disc;	new_ldisc->refcount = 0;	return ret;}struct tty_ldisc_ops tty_ldisc_N_TTY = {    .magic           = TTY_LDISC_MAGIC,    .name            = "n_tty",    .open            = n_tty_open,    .close           = n_tty_close,    .read            = n_tty_read,    .write           = n_tty_write,    ······};

2. 动态初始化

        在Linux驱动代码中,实行代码和数据分离的思想,将外部设备的信息(基地址、中断号等)另外封装,不放到驱动代码中,通过将封装后的信息以参数形式传递给驱动代码。与外部设备具体信息相关的初始化我们一般放在probe函数中进行。

        在中注册了一个平台驱动serial_imx_driver,串口设备会以平台设备的形式注册到平台总线,当串口设备和这个平台驱动匹配以后就会执行 serial_imx_driver.probe函数。

//imx.cstatic int serial_imx_probe(struct platform_device *pdev){	ret = serial_imx_probe_dt(sport, pdev);	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	base = devm_ioremap_resource(&pdev->dev, res);	sport->port.dev = &pdev->dev;	sport->port.mapbase = res->start;	sport->port.membase = base;	sport->port.type = PORT_IMX,	sport->port.iotype = UPIO_MEM;	sport->port.irq = platform_get_irq(pdev, 0);	sport->rxirq = platform_get_irq(pdev, 0);	sport->txirq = platform_get_irq(pdev, 1);	sport->rtsirq = platform_get_irq(pdev, 2);	sport->port.fifosize = 32;	sport->port.ops = &imx_pops;     //5.关键结构体的赋值	sport->port.flags = UPF_BOOT_AUTOCONF;	init_timer(&sport->timer);	sport->timer.function = imx_timeout;	sport->timer.data     = (unsigned long)sport;	sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg");	sport->clk_per = devm_clk_get(&pdev->dev, "per");	sport->port.uartclk = clk_get_rate(sport->clk_per);		sport->port.uartclk = clk_get_rate(sport->clk_per);	imx_ports[sport->port.line] = sport;	platform_set_drvdata(pdev, sport);	return uart_add_one_port(&imx_reg, &sport->port);}

3. 总结

        总结一下《串口驱动(一)》和《串口驱动(二)》两部分做了哪些初始化。

        如上图所示,前面的初始化部分,主要就是对以上的四个操作函数集进行填充、注册。

        现在串口驱动的整体框架也就出来了,tty_core层对于tty_io.c等文件,line discipline层对应于tty_ldisc.c等文件,serial_driver层对应serial_core.c、imx.c等文件。

        下一篇博客详细分析串口设备的打开过程,这里提前预示一下:用户打开串口设备时,会调用tty_open-->uart_open-->n_tty_open-->imx_startup,经过层层封装的调用,最终调用imx串口设备相关的硬件操作函数。

转载地址:http://lhuen.baihongyu.com/

你可能感兴趣的文章
记录运行代码的时间长短
查看>>
关于yii2的一些知识的学习笔述
查看>>
用纯php实现MVC框架,文件目录模仿yii2
查看>>
新开发的体重管理项目----用纯php模仿yii2框架建立的
查看>>
JavaScript面向对象编程指南 的笔记
查看>>
在 2016 年做 PHP 开发是一种什么样的体验?(一)
查看>>
PHP获取客户端的IP
查看>>
从头开始学习yii2---1.搭建yii2开发环境
查看>>
从头开始学习yii2---3.语言包的配置
查看>>
yii2-表单验证的一些规则
查看>>
索引相关问题
查看>>
php面试可能会被问道的技术题汇总
查看>>
php面试题1-线程和进程的区别(顺带提下协程)
查看>>
php面试题2-用到过的传输协议
查看>>
php面试题3-yii2和yii的不一样的地方
查看>>
IOS 一些好的框架和 技术大牛的博客
查看>>
Java 和 Object-c的区别
查看>>
Windows环境下Android NDK环境搭建
查看>>
NDK Build 用法(NDK Build)
查看>>
Android NDK开发起步Hello Jni
查看>>