Mercurial > ecos
view packages/redboot/current/src/io.c @ 147:d397fc472bcf
Merge from eCos master repository on 2001-01-05-06:43:02-GMT
| author | jlarmour |
|---|---|
| date | Fri, 05 Jan 2001 17:12:36 +0000 |
| parents | 6b5f480c6929 |
| children | 52c99470ec11 |
line wrap: on
line source
//========================================================================== // // io.c // // RedBoot I/O support // //========================================================================== //####COPYRIGHTBEGIN#### // // ------------------------------------------- // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.redhat.com/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations under // the License. // // The Original Code is eCos - Embedded Configurable Operating System, // released September 30, 1998. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are // Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND#### //========================================================================== //#####DESCRIPTIONBEGIN#### // // Author(s): gthomas // Contributors: gthomas // Date: 2000-07-14 // Purpose: // Description: // // This code is part of RedBoot (tm). // //####DESCRIPTIONEND#### // //========================================================================== #include "redboot.h" // GDB interface functions extern void ungetDebugChar(char c); 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); } } static bool mon_read_char_with_timeout(char *c) { bool res; 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; // Try input from 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(); 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); 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 on each channel so total amounts to desired value ms = ms / CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; 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); } } // // Read a line of input from the user // Return: // n: 'n' valid characters received // 0: '$' (GDB lead-in) // -1: No input before timeout // -2: ^C typed // int gets(char *buf, int buflen, int timeout) { char *ptr = buf; char c; bool res = false; static char last_ch = '\0'; while (true) { #ifdef CYGSEM_REDBOOT_FLASH_CONFIG if (script && *script) { c = *script++; } else #endif if ((timeout > 0) && (ptr == buf)) { mon_set_read_char_timeout(timeout); while (timeout > 0) { res = mon_read_char_with_timeout(&c); if (res) { // Got a character break; } timeout -= 50; } if (res == false) { return _GETS_TIMEOUT; // Input timed out } } else { mon_read_char(&c); } *ptr = '\0'; switch (c) { case 0x03: // ^C if (ptr == buf) { printf("^C\n"); return _GETS_CTRLC; } *ptr++ = c; break; case '\n': case '\r': // If previous character was the "other" end-of-line, ignore this one if (((c == '\n') && (last_ch == '\r')) || ((c == '\r') && (last_ch == '\n'))) { c = '\0'; break; } // End of line if (console_echo) { mon_write_char('\r'); mon_write_char('\n'); } last_ch = c; return _GETS_OK; case '\b': case 0x7F: // DEL if (ptr != buf) { if (console_echo) { mon_write_char('\b'); mon_write_char(' '); mon_write_char('\b'); } ptr--; } break; case '+': case '$': if (ptr == buf) { // Give up and try GDB protocol ungetDebugChar(c); // Push back character so stubs will see it return _GETS_GDB; } // Fall through - accept '$' at other than start of line default: if (console_echo) { mon_write_char(c); } *ptr++ = c; } last_ch = c; } } void dump_buf_with_offset(void *_p, CYG_ADDRWORD s, void *_base) { int i, c; cyg_uint8 *p = (cyg_uint8 *)_p; cyg_uint8 *base = (cyg_uint8 *)_base; if ((CYG_ADDRWORD)s > (CYG_ADDRWORD)p) { s = (CYG_ADDRWORD)s - (CYG_ADDRWORD)p; } while ((int)s > 0) { if (base) { printf("0x%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base); } else { printf("0x%08X: ", (CYG_ADDRWORD)p); } for (i = 0; i < 16; i++) { if (i < (int)s) { printf("%02X", p[i] & 0xFF); } else { printf(" "); } if ((i % 2) == 1) printf(" "); if ((i % 8) == 7) printf(" "); } printf(" |"); for (i = 0; i < 16; i++) { if (i < (int)s) { c = p[i] & 0xFF; if ((c < 0x20) || (c >= 0x7F)) c = '.'; } else { c = ' '; } printf("%c", c); } printf("|\n"); s -= 16; p += 16; } } void dump_buf(void *p, CYG_ADDRWORD s) { dump_buf_with_offset((cyg_uint8 *)p, s, 0); } bool verify_action(char *fmt, ...) { va_list ap; char ans[8]; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG unsigned char *hold_script = script; #endif va_start(ap, fmt); vprintf(fmt, ap); printf(" - are you sure (y/n)? "); #ifdef CYGSEM_REDBOOT_FLASH_CONFIG script = (unsigned char *)0; #endif gets(ans, sizeof(ans), 0); #ifdef CYGSEM_REDBOOT_FLASH_CONFIG script = hold_script; #endif return ((ans[0] == 'y') || (ans[0] == 'Y')); }
