新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > linux UART串口驱动开发文档

linux UART串口驱动开发文档

作者:时间:2012-09-06来源:网络收藏

#define _GET_CHAR(p) ((readb((p)->membase + W83697_DR)) 0xff)

#define _PUT_CHAR(p, c) writeb((c), (p)->membase + W83697_UARTDR)

2>. 接收发送状态.

#define UART_GET_RSR(p) ((readb((p)->membase + W83697_UARTRSR)) 0xff)

#define UART_PUT_RSR(p, c) writeb((c), (p)->membase + W83697_UARTRSR)

3>. 发送及接收中断状态.

#define UART_GET_CR(p) ((readb((p)->membase + W83697_UARTCR)) 0xff)

#define UART_PUT_CR(p,c) writeb((c), (p)->membase + W83697_UARTCR)

#define UART_GET_INT_STATUS(p) ((readb((p)->membase + W83697_UARTIIR)) 0xff)

4>. 以及其它的中断使能设置等, 在传送时打开传送中断即会产生传送中断.

#define UART_PUT_ICR(p, c) writeb((c), (p)->membase + W83697_UARTICR)

5>. FIFO的状态, 是否读空/是否写满; 每次读时必须读至FIFO空, 写时必须等到FIFO不满时才能写(要等硬件传送完) .

接收中断读空FIFO的判断:

status = UART_GET_FR(port);

while (UART_RX_DATA(status) max_count--) {

……

}

发送中断写FIFO: 当发送缓冲区中有数据要传送时, 置发送中断使能, 随后即产生传送中断, 此时FIFO为空, 传送半个FIFO大小的字节, 如果发送缓冲区数据传完,则关闭发送中断.

6>. 传送时可直接写数据口, 而不使用中断, 但必须等待检测FIFO的状态

do {

status = UART_GET_FR(port);

} while (!UART_TX_READY(status)); //wait for tx buffer not full...

3. 的参数配置

的参数主要包括如下几个参数,全部都记录在uart_port结构上,为静态的赋值,本串口支持6个设备,所以中就包括了6个port,一个串口对应一个port口,他们之间除了对应的中断号/寄存器起始基址/次设备号不同之外,其它的参数基本相同.

√串口对应中断, 这里六个串口,其中有3个串口使用的系统外部中断0/1/2, 其中另外几个中断用提GPIO中断,具体有关GPIO中断的内容可参见EP93XX芯片手册, GPIO中断共享一个系统中断向量,涉及中断共享的问题,后面将详述LINUX中的中断共享支持.

√串口时钟, 串口时钟用来转换计算须要设置到配置寄存器当中的波特率比值,其计算方法为:quot = (port->uartclk / (16 * baud)); baud为当前设置的波特率,可为115200等值, 取决于所选的串口时钟源, quot即为要设置到寄存器当中的比值.

√串口基址, 即串口所有配置寄存器基础址.

√串口次设备号(由驱动中的最低次设备号依次累加)

前面已经讲过了六个串口中断,这里详细列出对应情况如下,方便查找:

w83697的三个串口对应中断如下:

uart 1: 读写数据寄存器偏移为00x3F8, 对应系统外部中断INT_EXT[0].

uart 2: 读写数据寄存器偏移为00x2F8, 对应系统外部中断INT_EXT[1].

uart 3: 读写数据寄存器偏移为00x3e8, 对应系统外部中断INT_EXT[2].

uart 4: 读写数据寄存器偏移为00x3e8, 对应EGPIO[8].

w83977的两个串口对应中断如下:

uart 1: 读写数据寄存器偏移为00x3F8, 对应EGPIO[1].

uart 2: 读写数据寄存器偏移为00x2F8, 对应EGPIO[2].

下面列出其中一个具体的串口port的定义如下:

{

.port = {

.membase = (void *)W83697_UART4_BASE,

.mapbase = W83697_UART4_BASE,

.iotype = SERIAL_IO_MEM,

.irq = W83697_IRQ_UART4, //串口中断号

.uartclk = 1846100, //uart时钟,默认.

.fifosize = 8, //硬件fifo大小.

.ops = amba_pops, //底层驱动的硬件操作集,如开关中断等.

.flags = ASYNC_BOOT_AUTOCONF,

.line = 3, //串口在次设备数组中的索引号,须注意从0计起…

},

.dtr_mask = 0,

.rts_mask = 0,

}

4. 串口驱动的底层接口函数

驱动文件:-2.4.21/drivers/serial/Ep93xx_w83697.c

相关文件: -2.4.21/drivers/serial/core.c 下面详述.

函数: w83697uart_rx_chars(struct uart_port *port, struct pt_regs *regs)

描述: 串口接收数据中断, 此函数中应当注意的要点如下:

接收数据时,要注意判断FIFO是否读空(参见上述2点中说明).

接收数据放入flip缓冲区,此缓冲区专供缓存中断中接收到的数据,是最原始的串口数据,为更上一层中各种终端处理模式的原始数据,可以进行各种加工处理。

接收数据到flip缓冲区中时,须根据硬件接收状态,置每一个接收到的字符的接收标志,放在flag_buf_ptr当中, 标志类型有TTY_NORMAL/ TTY_PARITY/ TTY_FRAME等,分别表示正常/校验出错/帧出错(无停止位)等.

每接收数据之后,会通过在退出中断前调用tty_flip_buffer_push()来往tq_timer任务列表中加一个队列任务,串口的队列任务主要是负责将中断接收到flip缓冲区中的数据往上传输至终端终冲区, 队列任务的机制将在后面介绍,它是一种异步执行机制,在软中断中触发执行.

函数: static void w83697uart_tx_chars(struct uart_port *port)

描述: 串口发送数据中断, 发送中断中要做的事比较少,比起接收中断简单了好多,注意事项如下:

当上层要发送数据时,就会打开串口发送中断,此时FIFO为空,传送半个FIFO大小数据即退出, 通常打开中断是通过更上一层的uart_flush_chars()调用,最终调用的是w83697uart_start_tx().

检测当没有数据要传输的时候,关闭传送中断,在传送之前与传送完之后都有检测.

最重要的一点是如果传送缓冲区当中的字符数已经小于WAKEUP_CHARS, 则可以唤醒当前正在使用串口进行传送的进程,这里是通过tasklet机制来完成,这也是一异步执行机制.

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

linux相关文章:linux教程




评论


相关推荐

技术专区

关闭