Chinaunix首页 | 论坛 | 博客
  • 博客访问: 569268
  • 博文数量: 137
  • 博客积分: 4040
  • 博客等级: 上校
  • 技术积分: 1584
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-08 13:05
文章分类

全部博文(137)

文章存档

2011年(10)

2010年(23)

2009年(104)

分类: LINUX

2009-08-12 00:27:48

 

/*
 * linux/kernel/serial.c
 *
 * (C) 1991 Linus Torvalds
 */


/*
 *    serial.c
 *
 * This module implements the rs232 io functions
 *    void rs_write(struct tty_struct * queue);
 *    void rs_init(void);
 * and all interrupts pertaining to serial IO.
 */


#include <linux/tty.h>
#include <linux/sched.h>
#include <asm/system.h>
#include <asm/io.h>

#define WAKEUP_CHARS (TTY_BUF_SIZE/4)//当写队列中含有WAKEUP_CHARS 个字符时,就开始发送(向串口发送)


extern void rs1_interrupt(void);// 串行口1 的中断处理程序(rs_io.s, 34)。

extern void rs2_interrupt(void);// 串行口2 的中断处理程序(rs_io.s, 38)。


static void init(int port)//// 初始化串行端口,port串行端口基地址, port: 串口1 - 0x3F8,串口2 - 0x2F8。

{
    outb_p(0x80,port+3);    /* set DLAB of line control reg *//* 线路控制寄存器LCR,设置线路控制寄存器的DLAB 位(位7) */
    outb_p(0x30,port);    /* LS of divisor (48 -> 2400 bps *//*除数锁存寄存器LSB, 发送波特率因子低字节,0x30->2400bps */
    outb_p(0x00,port+1);    /* MS of divisor *//* 除数锁存寄存器MSB,发送波特率因子高字节,0x00 */
    outb_p(0x03,port+3);    /* reset DLAB *//* 线路控制寄存器LCR,复位DLAB 位,数据位为8 位 */
    outb_p(0x0b,port+4);    /* set DTR,RTS, OUT_2 *//*MODEN控制寄存器, 设置DTR,RTS,辅助用户输出2 */
    outb_p(0x0d,port+1);    /* enable all intrs but writes *//*中断充许寄存器IER, 除了写(写保持空)以外,允许所有中断源中断 */
    (void)inb(port);    /* read data port to reset things (?) *//* 读数据口,以进行复位操作(?) */
}

void rs_init(void)//// 初始化串行中断程序和串行接口

{
    set_intr_gate(0x24,rs1_interrupt);// 设置串行口1 的中断门向量(硬件IRQ4 信号)。

    set_intr_gate(0x23,rs2_interrupt);// 设置串行口2 的中断门向量(硬件IRQ3 信号)。

    init(tty_table[1].read_q.data);// 初始化串行口1

    init(tty_table[2].read_q.data);// 初始化串行口2

    outb(inb_p(0x21)&0xE7,0x21);// 允许主8259A 芯片的IRQ3,IRQ4 中断信号请求

}

/*
 * This routine gets called when tty_write has put something into
 * the write_queue. It must check wheter the queue is empty, and
 * set the interrupt register accordingly
 *
 *    void _rs_write(struct tty_struct * tty);
 */

void rs_write(struct tty_struct * tty)//串口数据发送函数

{
    cli();//关中断

    if (!EMPTY(tty->write_q))//TTY写队列不为空

        outb(inb_p(tty->write_q.data+1)|0x02,tty->write_q.data+1);//则从0x3f9(或0x2f9) 首先读取中断允许寄存器内容,添上发送保持寄存器中断允许标志(位1)后,再写回该寄存器,从而引发中断,其中断处理过程由rs_io.s来完成

    sti();//开中断

}

阅读(723) | 评论(0) | 转发(0) |
0

上一篇:rs_io.s

下一篇:math_emulate.c

给主人留下些什么吧!~~