在TTY任务中执行一个循环,这个循环将轮询每一个TTY,处理它的事件,包括从键盘缓冲区读取数据、显示字符等内容。 在task_tty ( )中,通过循环来处理每一个TTY的读和写操作,读写操作全都放在了tty_do_read( )和tty_do_write( )两个函数中。
当TTY任务开始运行时,所有TTY都将被初始化,并且全局变量nr_current_console会被赋值为0。然后循环开始并一直进行下去。对于每一个TTY,首先执行tty_do_read(),它将调用keyboard_read()并将读入的字符交给函数in_process( )来处理,如果是需要输出的字符,会被in_process( )放入当前接受处理的TTY的缓冲区中。然后tty_do_write( )会接着执行,如果缓冲区中有数据,就被送入out_char显示出来。
/*======================================================================*
task_tty
*======================================================================*/
PUBLIC void task_tty()
{
TTY* p_tty;
init_keyboard();
for (p_tty=TTY_FIRST;p_tty<TTY_END;p_tty++) {
init_tty(p_tty);
}
nr_current_console = 0;
while (1) {
for (p_tty=TTY_FIRST;p_tty<TTY_END;p_tty++) {
tty_do_read(p_tty);
tty_do_write(p_tty);
}
}
}
为了让输入和输出分离,被keyboard_read( )调用的in_process( )不应该再直接回显字符,而应该将回显的任务交给TTY来完成,这样,我们就需要为每个TTY建立一块缓冲区,用以放置将被回显的字符。
/* TTY */
typedef struct s_tty
{
u32 in_buf[TTY_IN_BYTES]; /* TTY 输入缓冲区 */
u32* p_inbuf_head; /* 指向缓冲区中下一个空闲位置 */
u32* p_inbuf_tail; /* 指向键盘任务应处理的键值 */
int inbuf_count; /* 缓冲区中已经填充了多少 */
struct s_console * p_console;
}TTY;
/*======================================================================*
init_tty
*======================================================================*/
PRIVATE void init_tty(TTY* p_tty)
{
p_tty->inbuf_count = 0;
p_tty->p_inbuf_head = p_tty->p_inbuf_tail = p_tty->in_buf;
int nr_tty = p_tty - tty_table;
p_tty->p_console = console_table + nr_tty;
}
/*======================================================================*
tty_do_read
*======================================================================*/
PRIVATE void tty_do_read(TTY* p_tty)
{
if (is_current_console(p_tty->p_console)) {
keyboard_read(p_tty);
}
}
/*======================================================================*
tty_do_write
*======================================================================*/
PRIVATE void tty_do_write(TTY* p_tty)
{
if (p_tty->inbuf_count) {
char ch = *(p_tty->p_inbuf_tail);
p_tty->p_inbuf_tail++;
if (p_tty->p_inbuf_tail == p_tty->in_buf + TTY_IN_BYTES) {
p_tty->p_inbuf_tail = p_tty->in_buf;
}
p_tty->inbuf_count--;
out_char(p_tty->p_console, ch);
}
}
-----------console.c
/*======================================================================*
out_char
*======================================================================*/
PUBLIC void out_char(CONSOLE* p_con, char ch)
{
u8* p_vmem = (u8*)(V_MEM_BASE + disp_pos);
*p_vmem++ = ch;
*p_vmem++ = DEFAULT_CHAR_COLOR;
disp_pos += 2;
set_cursor(disp_pos/2);
}