`

Linux下层串行API

 
阅读更多

下层串行API
--------------------

本文简要介绍了新的串行驱动的某些方面。这并不完整,有任何问题请联系<rmk[AT]arm.linux.org[DOT]uk>

在serial_amba.c可以找到所涉及的实现部分。

下层串行硬件驱动
--------------------------------

下层串行硬件驱动主要为核心串行驱动提供端口信息(在uart_port中定义的)和一组控制方法(在uart_port中定义的)。下层驱动同时也处理来自端口的中断和提供控制台支持。


控制台支持
---------------
串行核心提供了一些辅助函数。这包括识别正确的端口结构体(通过uart_get_console)和解析命令行参数(即uart_parse_options)。

锁定
-------

下层硬件驱动需使用port->lock执行必要的锁操作。也有一些例外(在下面的uart_ops列表中会描述到)。

有三种锁。单端口自旋锁,单端口临时缓冲区信号量和全局信号量。

从核心驱动来看,port->lock锁定以下数据:
port->mctrl
port->icount
info->xmit.head (circ->head)
info->xmit.tail (circ->tail)

下层驱动可以随意使用这种锁来提供任何锁定操作。

下层驱动使用info->tmpbuf_sem锁来防止多线程访问用作端口写的info->tmpbuf弹性缓冲区。

port_sem信号量是被用来保护端口的,防止在不恰当的时间添加删除或重新配置端口。


uart_ops
--------
struct uart_ops {
u_int (*tx_empty)(struct uart_port *);
void (*set_mctrl)(struct uart_port *, u_int mctrl);
u_int (*get_mctrl)(struct uart_port *);
void (*stop_tx)(struct uart_port *, u_int from_tty);
void (*start_tx)(struct uart_port *, u_int nonempty, u_int from_tty);
void (*stop_rx)(struct uart_port *);
void (*enable_ms)(struct uart_port *);
void (*break_ctl)(struct uart_port *, int ctl);
int (*startup)(struct uart_port *, struct uart_info *);
void (*shutdown)(struct uart_port *, struct uart_info *);
void (*change_speed)(struct uart_port *, u_int cflag, u_int iflag, u_int quot);
void (*pm)(struct uart_port *, u_int state, u_int oldstate);
int (*set_wake)(struct uart_port *, u_int state);

/*
* Return a string describing the type of the port
*/
const char *(*type)(struct uart_port *);

/*
* Release IO and memory resources used by the port.
* This includes iounmap if necessary.
*/
void (*release_port)(struct uart_port *);

/*
* Request IO and memory resources used by the port.
* This includes iomapping the port if necessary.
*/
int (*request_port)(struct uart_port *);
void (*config_port)(struct uart_port *, int);
int (*verify_port)(struct uart_port *, struct serial_struct *);
int (*ioctl)(struct uart_port *, u_int, u_long);
};


uart_ops结构体是串行核心serial_core和硬件专用驱动之间的主要接口。它包含控制硬件的所有方法。


u_int (*tx_empty)(struct uart_port *port);
该函数将检查参数port所对应的发送队列是否为空。如果为空,该函数应返回TIOCSER_TEMT,否则返回0。如果端口并不支持这一操作,那么他应返回TIOCSER_TEMT。

void (*set_mctrl)(struct uart_port *port, u_int mctrl);
该函数将参数port所对应的调制解调器控制线的值设为参数mctrl的值。mctrl相关的位如下所示:
- TIOCM_RTS RTS 信号.
- TIOCM_DTR DTR 信号.
- TIOCM_OUT1 OUT1 信号.
- TIOCM_OUT2 OUT2 信号.
如果其中某一位被置位,对应的信号将将被置为有效。如果被复位,对应的信号将被值为无效。

u_int (*get_mctrl)(struct uart_port *port);
返回调制解调器控制输入的现有状态。输出的状态则不应被返回,因为核心知道这些状态。这些状态信息包括:
- TIOCM_DCD DCD 信号状态
- TIOCM_CTS CTS 信号状态
- TIOCM_DSR DSR 信号状态
- TIOCM_RI RI 信号状态
如果信号被置为有效,则对应位将被置位。如果端口不支持CTS、DCD或DSR,驱动应指出这些信号将永久置为有效。如果RI不可用,其信号不应置为有效。

void (*stop_tx)(struct uart_port *port, u_int from_tty);
停止传输字符。这有可能因为CTS变成无效或tty层指示因为遇到Xoff字符而停止传输。

驱动应有可能就停止传输。

void (*start_tx)(struct uart_port *port, u_int nonempty, u_int from_tty);
开始传输字符。

void (*stop_rx)(struct uart_port *port);
停止接收字符;端口在关闭的过程中。

void (*enable_ms)(struct uart_port *port);
调制解调器状态中断使能。

void (*break_ctl)(struct uart_port *port, int ctl);
控制暂停信号的传输。如果ctl不为零,中断信号将被传输。当有凭借为零的ctl产生的其他调用时,该信号应终止。

int (*startup)(struct uart_port *port, struct uart_info *info);
抢占所有中断资源,初始化所有下层驱动状态。为接收使能端口。它不能使RTS和DTR有效;通过另外调用的set_mctrl可以做到这一点。

void (*shutdown)(struct uart_port *port, struct uart_info *info);
禁用端口,禁用任何有效果的暂停条件,并且释放所有的中断资源。它不能使RTS和DTR无效;通过另外调用的set_mctrl可以做到这一点。

void (*change_speed)(struct uart_port *port, u_int cflag, u_int iflag, u_int quot);
或set_termios(port,termios,oldtermios)
改变端口参数,包括字长,奇偶校验位,停止位。更新read_status_mask和ignore_status_mask来指示我们在接收时所感兴趣的事件类型。相关的termios->c_cflag位如下所示:
CSIZE - 字长
CSTOPB - 2个停止位
PARENB - 奇偶校验位使能
PARODD - 奇校验位(当PARENB被强制使能时)
CREAD - 字符接收使能(如果没有置位,仍然从端口接收字符,但这些字符都要被丢弃掉)
CRTSCTS - 如果被置位,使能CTS状态改变报告
CLOCAL - 如果没有置位,使能调制解调器状态改变报告
相关的termios->c_iflag bits位如下所示:
INPCK - 使能帧和奇偶校验错误事件,并传输到TTY层
BRKINT
PARMRK - 这两个都能使能暂停事件,并传输到TTY层。

IGNPAR - 忽略奇偶校验和帧错误
IGNBRK - 忽略暂停错误,如果IGNPAR也被置位,则忽略溢出错误。
iflag每一位的交互含义如下所示(以奇偶校验错误为例):
奇偶校验错误 INPCK IGNPAR
None n/a n/a 字符被接收
Yes n/a 0 字符被丢弃
Yes 0 1 字符被接受,并被标示为TTY_NORMAL
Yes 1 1 字符被接受,并被标示为TTY_PARITY

其它flags也会被使用(例如,xon/xoff字符),如果你的硬件支持硬件“软”流控。

void (*pm)(struct uart_port *port, u_int state, u_int oldstate);
执行任何特定端口操作的电源管理。参数state指示新的状态(在ACPI D0-D3中定义的),oldstate指示前一个状态。本质上,D0指全部开,D3指电源关闭。
该函数不能用来抢占任何资源。
该函数会在端口最初打开和最后关闭时调用,除了端口作为系统控制台的情况。这种事情总会发生,即使CONFIG_PM没有被置位。


const char *(*type)(struct uart_port *port);
返回一个描述特定端口的常量string的指针,或当遇到string为“unknown”时返回NULL。

void (*release_port)(struct uart_port *port);
释放任何被端口占用的内存及IO资源。

int (*request_port)(struct uart_port *port);
申请端口所需的内存和IO资源。如果失败,当函数返回时,应该没有任何资源被注册,并且在失败时-EBUSY。

void (*config_port)(struct uart_port *port, int type);
执行所有端口所需的自动配置步骤。‘type’包括所需配置的掩码。UART_CONFIG_TYPE指出端口需要探测和识别。port->type用被置位所发现的类型,或者是如果没有端口被发现,则置位为PORT_UNKNOWN。
UART_CONFIG_IRQ指出中断信号的自动配置,而这需使用标准内核自动探测技术来探测。在平台中固件内置有中断的端口是没有必要的(例如,片上系统实现)。

int (*verify_port)(struct uart_port *port, struct serial_struct *serinfo);
验证新的串行端口信息,包括serinfo是否适合这种端口类型。

int (*ioctl)(struct uart_port *port, u_int cmd, u_long arg);
执行任何特定的IOCTL操作。IOCTL命令必须使用标准编号系统中在<asm/ioctl.h>所定义的。

其它函数
---------------

uart_update_timeout(port,cflag,baud)
Update the FIFO drain timeout, port->timeout, according to the
number of bits, parity, stop bits and baud rate.

Locking: caller is expected to take port->lock
Interrupts: n/a

uart_get_baud_rate(port,termios,old,min,max)
Return the numeric baud rate for the specified termios, taking
account of the special 38400 baud "kludge". The B0 baud rate
is mapped to 9600 baud.

If the baud rate is not within min..max, then if old is non-NULL,
the original baud rate will be tried. If that exceeds the
min..max constraint, 9600 baud will be returned. termios will
be updated to the baud rate in use.

Note: min..max must always allow 9600 baud to be selected.

Locking: caller dependent.
Interrupts: n/a

uart_get_divisor(port,baud)
Return the divsor (baud_base / baud) for the specified baud
rate, appropriately rounded.

If 38400 baud and custom divisor is selected, return the
custom divisor instead.

Locking: caller dependent.
Interrupts: n/a

static int uart_match_port(struct uart_port *port1, struct uart_port *port2);
该效用函数用来确定两个uart_port结构体是否描述的是同一个端口。

uart_write_wakeup(port)
A driver is expected to call this function when the number of
characters in the transmit buffer have dropped below a threshold.

Locking: port->lock should be held.
Interrupts: n/a

int uart_register_driver(struct uart_driver *drv);
用核心驱动注册一个串行驱动。我们依次用tty层注册和初始化核心驱动的每个端口状态。

drv->port should be NULL, and the per-port structures should be
registered using uart_add_one_port after this call has succeeded.

Locking: none
Interrupts: enabled

void uart_unregister_driver(struct uart_driver *drv);
在驱动中移除从核心驱动中的所有涉及到的。下层驱动迎移除它所有的端口。

uart_suspend_port()

uart_resume_port()

uart_add_one_port()

uart_remove_one_port()

其它注解
-----------
有可能在某一天会丢弃掉uart_port中的‘unused’项,并允许下层驱动用核心注册它们自己的uart_port。这会允许驱动使用uart_port项,像用指向一个包含uart_port项和扩展项的结构体的指针一样,如此:
struct my_port {
struct uart_port port;
int my_stuff;
};

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/king526/archive/2006/12/06/1432248.aspx

分享到:
评论

相关推荐

    打印机出现 远程下层文档 解决办法

    打印机出现 远程下层文档 解决办法,确实管用的

    解析Linux的VFS机制

    本文侧重于通过具体的代码分析来解释 Linux 内核中 VFS 的内在机制,在这过程中会涉及到上层文件系统调用和下层实际文件系统的如何挂载。文章试图从一个比较高的角度来解释 Linux 下的 VFS 文件系统机制。

    配置RTLinux系统

    RTLinux系统是众多实时操作系统中的一种, 它是美国新墨西哥州大学计算机系采用低层编程的方法 开发的,它在Linux内核的下层构建RTLinux内核

    javascript 图片慢慢下层效果

    javascript 图片慢慢下层效果

    远程下层文档解决办法

    远程下层文档是个很头痛的东西发一个解决方法希望对你们有帮助

    Linux/UNIX系统编程手册 下.pdf

    linux系统编程手册,下层,下层主要写了 socket ,进程间通信方式等. 实用价值非常高

    下层煤应力分布规律与巷道破坏特征研究

    本文针对当前近距离煤层下煤层应力分布规律与巷道破坏特征进行研究,通过岩石力学理论分析研究了下层煤受力情况,在理论分析基础上,运用FLAC3D软件建立了同煤集团燕子山矿煤层数值模型,通过模拟得出了下层煤应力分布...

    基于RTSP的linux环境编程的客户端实现

    主要用来控制具有实时特性的数据的发送,但其本身并不用于传送流媒体数据,而必须依赖下层传输协议(如RTP/RTCP)所提供的服务来完成流媒体数据的传送。RTSP负责定义具体的控制信息、操作方法、状态码,以及描述与RTP...

    Linux IO数据通道分享

    1.虚拟文件系统层:屏蔽下层具体文件系统操作的差异,为上层的操作提供一个统一的接口。因为有了这个层次,所以可以把设备抽象成文件,使得操作设备就像操作文件一样简单。 2.具体的文件系统层:不同的文件系统...

    WindowsAPI参考大全

    不过,这也导致了非常多的程序员在类库面前“固步自封”,对下层API函数的强大功能一无所知。 实际上。程序员要想开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数。虽然类库和控件使应用...

    嵌入式Linux应用程序开发详解 完整版 PDF格式

    嵌入式Linux应用程序开发详解完整版 共有十二章,对于开发人员理解上层与下层是如何调用的有很大帮助

    晋北煤矿5-103综采面过下层空巷支护技术

    以霍州煤电集团晋北煤矿5-103综采工作面为研究对象,设计、分析了"整体充填"和"支护+部分充填"两种过下层空巷技术方案,确定对集中轨道巷与5-103工作面立交区域采用矸石配合高水材料进行整体充填,并提出了过空巷技术...

    转--linux网络协议栈笔记

    大家都知道TCP/IP协议栈现在是世界上最流行的网络协议栈,恐怕它的...不仅使得上层应用开发者可以无需关心下层架构或者内部机制,从而相对透明的操作网络。这个明显的层次结构也可以在Linux内核的网络协议栈中观察到。

    基于matlab的主从博弈 下层KKT条件强对偶处理双线性源码+详细注释.zip

    基于matlab的主从博弈 下层KKT条件 强对偶处理双线性源码+详细注释.zip基于matlab的主从博弈 下层KKT条件 强对偶处理双线性源码+详细注释.zip基于matlab的主从博弈 下层KKT条件 强对偶处理双线性源码+详细注释.zip...

    解决 该文档未能打印,本地下层文档. 怎样删除无法删除的打印任务.zip

    解决 该文档未能打印,本地下层文档. 怎样删除无法删除的打印任务.zip

    基于matlab的主从博弈下层KKT条件强对偶处理双线性源码+项目说明+详细注释.zip

    基于matlab的主从博弈下层KKT条件强对偶处理双线性源码+项目说明+详细注释.zip # stackelberg_Game 主从博弈的尝试 另外发现YALMIP的kkt命令能很方便的把下层问题转化为KKT系统 复刻论文 基于matlab的主从博弈下层...

    Linux 编程白皮书

    操作系统必须和作为其基础的硬件系统紧密地协同工作。操作系统需要只有硬件能提供的特定服务。为了完全理解 L i n u x操作系统,需要了解它下层的硬件基础知识。

    近距离煤层上层开采对下层巷道的影响分析

    近距离煤层分层开采时,上分层的开采势必会影响下分层先期布置的开拓巷道围岩的稳定。然而上分层开采造成的超前支承压力对下分层巷道影响的过程很难监测掌握。运用数值模拟软件FLAC建立模型,对上分层开采过程中工作面...

    本科-移动通信-76分.docx

    (A) 某码树种下层分支的一部分码被使用 (B) 某码树种下层分支的所有码都被使用 (C) 某码树种下层分支的一部分码没有被使用 (D) 某码树种下层分支的所有码都没有被使用 分值:4 答题错误 得分:0 2. 下一代移动通信...

Global site tag (gtag.js) - Google Analytics