📄 io.c
字号:
//==========================================================================//// io.c//// RedBoot I/O support////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.// Copyright (C) 2002, 2003 Gary Thomas//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): gthomas// Contributors: gthomas,hmt,jlarmour// Date: 2000-07-14// Purpose: // Description: // // This code is part of RedBoot (tm).////####DESCRIPTIONEND####////==========================================================================#include "redboot.h"#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS// GDB interface functionsextern void ungetDebugChar(char c);#endifstatic voiddo_channel(int argc, char *argv[]);#ifdef CYGPKG_REDBOOT_ANY_CONSOLERedBoot_cmd("channel", "Display/switch console channel", "[-1|<channel number>]", do_channel );#elseRedBoot_cmd("channel", "Display/switch console channel", "[<channel number>]", do_channel );#endifstatic voiddo_channel(int argc, char *argv[]){ int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); if (argc == 2) { #ifdef CYGPKG_REDBOOT_ANY_CONSOLE if (strcmp( argv[1], "-1") == 0) { console_selected = false; console_echo = true; } else #endif { unsigned long chan; if ( !parse_num( argv[1], &chan, NULL, NULL) ) { diag_printf("** Error: invalid channel '%s'\n", argv[1]); } else { if (chan < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS) { CYGACC_CALL_IF_SET_CONSOLE_COMM(chan); CYGACC_CALL_IF_SET_DEBUG_COMM(chan); if (chan != cur) console_echo = true; } else { diag_printf("**Error: bad channel number '%s'\n", argv[1]); } } } } /* else display */ else { diag_printf("Current console channel id: ");#ifdef CYGPKG_REDBOOT_ANY_CONSOLE if (!console_selected) diag_printf("-1\n"); else#endif diag_printf("%d\n", cur); }}void mon_write_char(char c){ hal_virtual_comm_table_t *__chan;#ifdef CYGPKG_REDBOOT_ANY_CONSOLE if (!console_selected) { int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); int i; // Send output to all channels for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++) { CYGACC_CALL_IF_SET_CONSOLE_COMM(i); __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_PUTC(*__chan, c); } CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); } else #endif { __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); if (__chan) CYGACC_COMM_IF_PUTC(*__chan, c); else { __chan = CYGACC_CALL_IF_DEBUG_PROCS(); CYGACC_COMM_IF_PUTC(*__chan, c); } }}static void mon_read_char(char *c){ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); if (__chan) *c = CYGACC_COMM_IF_GETC(*__chan); else { __chan = CYGACC_CALL_IF_DEBUG_PROCS(); *c = CYGACC_COMM_IF_GETC(*__chan); }}#ifdef CYGPKG_REDBOOT_ANY_CONSOLEstatic int _mon_timeout;#endifstatic boolmon_read_char_with_timeout(char *c){ bool res = false; hal_virtual_comm_table_t *__chan;#ifdef CYGPKG_REDBOOT_ANY_CONSOLE if (!console_selected) { int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); int i, j, tot; // Try input from all channels tot = 0; while (tot < _mon_timeout) { for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++, tot++) { CYGACC_CALL_IF_SET_CONSOLE_COMM(i); __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c); if (res) { // Input available on this channel, make it be the console if (*c != '\0') { // Don't chose this unless real data have arrived console_selected = true; CYGACC_CALL_IF_SET_DEBUG_COMM(i); // Disable interrupts on all channels but this one for (j = 0; j < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; j++) { if (i != j) { CYGACC_CALL_IF_SET_CONSOLE_COMM(j); __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_DISABLE); } } CYGACC_CALL_IF_SET_CONSOLE_COMM(i); return res; } } } } CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); } else #endif { __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); if (__chan) res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c); else { __chan = CYGACC_CALL_IF_DEBUG_PROCS(); res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c); } } return res;}static voidmon_set_read_char_timeout(int ms){ hal_virtual_comm_table_t *__chan;#ifdef CYGPKG_REDBOOT_ANY_CONSOLE if (!console_selected) { int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); int i; // Set timeout to minimum on each channel; total amounts to desired value _mon_timeout = ms; ms = 1; for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++) { CYGACC_CALL_IF_SET_CONSOLE_COMM(i); if ((__chan = CYGACC_CALL_IF_CONSOLE_PROCS()) != 0) { CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, ms); } } CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); } else #endif { if ((__chan = CYGACC_CALL_IF_CONSOLE_PROCS()) != 0) { CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, ms); } if ((__chan = CYGACC_CALL_IF_DEBUG_PROCS()) != 0) { CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, ms); } }}//// Test for ^C on the console. CAUTION! discards all console input//bool_rb_break(int timeout){ char c; mon_set_read_char_timeout(timeout); if (mon_read_char_with_timeout(&c)) { if (c == 0x03) { // Test for ^C return true; } } return false;}#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT#define __STRINGIFY(x) #x#define _STRINGIFY(x) __STRINGIFY(x)#define _STARTUP_STR _STRINGIFY(CYG_HAL_STARTUP) "}"//// Read a character from script.// Return true if script character found, false if not.//static intgetc_script(char *cp){ static bool newline = true; bool skip; while (script && *script) { if (newline && *script == '{') { skip = false; ++script; // skip if it isn't for this startup type if (strncmp(script, _STARTUP_STR, strlen(_STARTUP_STR))) skip = true; // skip past "{...}" while (*script && *script++ != '}') ; // skip script line if neccessary if (skip) { while (*script && *script++ != '\n') ; } else newline = false; } else { *cp = *script++; if (*cp == '\n') { newline = true; } else { newline = false; } return true; } } return false;}#endif#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0#define _CL_NUM_LINES CYGNUM_REDBOOT_CMD_LINE_EDITING // Number of lines to keepstatic char _cl_lines[_CL_NUM_LINES][CYGPKG_REDBOOT_MAX_CMD_LINE];static int _cl_index = -1; // Last known command linestatic int _cl_max_index = -1; // Last command in buffers#ifdef CYGBLD_REDBOOT_CMD_LINE_HISTORYstatic void expand_history(char *);#endif#endif//// Read a line of input from the user// Return:// _GETS_OK: 'n' valid characters received// _GETS_GDB: '$' (GDB lead-in)// _GETS_TIMEOUT: No input before timeout// _GETS_CTRLC: ^C typed//// if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0// Command line history support// ^P - Select previous line from history// ^N - Select next line from history// ^A - Move insertion [cursor] to start of line// ^E - Move cursor to end of line// ^B - Move cursor back [previous character]// ^F - Move cursor forward [next character]//int_rb_gets_preloaded(char *buf, int buflen, int timeout){ char *ip = buf; // Insertion point char *eol = buf; // End of line char c; bool res = false; static char last_ch = '\0'; int _timeout;#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 int _index = _cl_index; // Last saved line char *xp;#endif // Display current buffer data while (*eol) { mon_write_char(*eol++); } ip = eol; while (true) {#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT if (getc_script(&c)) do_idle(false); else#endif if ((timeout > 0) && (eol == buf)) {#define MIN_TIMEOUT 50 _timeout = timeout > MIN_TIMEOUT ? MIN_TIMEOUT : timeout; mon_set_read_char_timeout(_timeout); while (timeout > 0) { res = mon_read_char_with_timeout(&c); if (res) { // Got a character do_idle(false); break; } timeout -= _timeout; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -