📄 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 Red Hat, Inc.
// Copyright (C) 2002 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 functions
extern void ungetDebugChar(char c);
#endif
static void
do_channel(int argc, char *argv[]);
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
RedBoot_cmd("channel",
"Display/switch console channel",
"[-1|<channel number>]",
do_channel
);
#else
RedBoot_cmd("channel",
"Display/switch console channel",
"[<channel number>]",
do_channel
);
#endif
static void
do_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_CONSOLE
static int _mon_timeout;
#endif
static bool
mon_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 void
mon_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);
}
}
}
#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 int
getc_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
//
// 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
//
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
//
// 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]
//
#define _CL_NUM_LINES CYGNUM_REDBOOT_CMD_LINE_EDITING // Number of lines to keep
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -