📄 net_io.c
字号:
//==========================================================================//// net/net_io.c//// Stand-alone network logical I/O support for RedBoot////==========================================================================//####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>#include <eth_drv.h> // Logical driver interfaces#include <net/net.h>#include <cyg/hal/hal_misc.h> // Helper functions#include <cyg/hal/hal_if.h> // HAL I/O interfaces#include <cyg/hal/drv_api.h>#include <cyg/hal/hal_intr.h>#ifdef CYGSEM_REDBOOT_FLASH_CONFIG#include <flash_config.h>RedBoot_config_option("GDB connection port", gdb_port, ALWAYS_ENABLED, true, CONFIG_INT );RedBoot_config_option("Network debug at boot time", net_debug, ALWAYS_ENABLED, true, CONFIG_BOOL );// Note: the following options are related. If 'bootp' is false, then// the other values are used in the configuration. Because of the way// that configuration tables are generated, they should have names which// are related. The configuration options will show up lexicographically// ordered, thus the peculiar naming. In this case, the 'use' option is// negated (if false, the others apply) which makes the names even more// confusing.RedBoot_config_option("Use BOOTP for network configuration", bootp, ALWAYS_ENABLED, true, CONFIG_BOOL );RedBoot_config_option("Local IP address", bootp_my_ip, "bootp", false, CONFIG_IP );RedBoot_config_option("Default server IP address", bootp_server_ip, "bootp", false, CONFIG_IP );#endif#define TCP_CHANNEL CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS#ifdef DEBUG_TCPint show_tcp = 0;#endif static tcp_socket_t tcp_sock;static int state;static int _timeout = 500;static int orig_console, orig_debug;static int in_buflen = 0;static unsigned char in_buf[128];static unsigned char *in_bufp;static int out_buflen = 0;static unsigned char out_buf[256];static unsigned char *out_bufp;// Functions in this modulestatic void net_io_flush(void);static void net_io_revert_console(void);static void net_io_wait_for_connection(void);static cyg_boolnet_io_getc_nonblock(void* __ch_data, cyg_uint8* ch){ if (in_buflen == 0) { __tcp_poll(); if (tcp_sock.state == _CLOSE_WAIT) { // This connection is breaking if (tcp_sock.data_bytes == 0) { __tcp_close(&tcp_sock); } return false; } if (tcp_sock.state != _ESTABLISHED) return false; in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf)); in_bufp = in_buf;#ifdef DEBUG_TCP if (show_tcp && (in_buflen > 0)) { int old_console; old_console = start_console(); printf("%s:%d\n", __FUNCTION__, __LINE__); dump_buf(in_buf, in_buflen); end_console(old_console); }#endif // DEBUG_TCP } if (in_buflen) { *ch = *in_bufp++; in_buflen--; return true; } else { return false; }}static cyg_uint8net_io_getc(void* __ch_data){ cyg_uint8 ch; int idle_timeout = 100; // 10ms CYGARC_HAL_SAVE_GP(); while (true) { if (net_io_getc_nonblock(__ch_data, &ch)) break; if (tcp_sock.state == _CLOSED) { // The connection is gone if (redboot_in_stub) { // handle gdb "detach" command by waiting for // a new connection. net_io_wait_for_connection(); } else { // Revert RedBoot command line console. net_io_revert_console(); net_io_init(); ch = '\n'; break; } } if (--idle_timeout == 0) { net_io_flush(); idle_timeout = 100; } else { CYGACC_CALL_IF_DELAY_US(100); } } CYGARC_HAL_RESTORE_GP(); return ch;}static voidnet_io_flush(void){ int n; char *bp = out_buf; while (out_buflen) { if (tcp_sock.state == _CLOSE_WAIT) { // This connection is tring to close __tcp_close(&tcp_sock); } if (tcp_sock.state == _CLOSED) { // The connection is gone! net_io_revert_console(); net_io_init(); break; }#ifdef DEBUG_TCP if (show_tcp) { int old_console; old_console = start_console(); printf("%s.%d\n", __FUNCTION__, __LINE__); dump_buf(out_buf, out_buflen); end_console(old_console); }#endif // SHOW_TCP n = __tcp_write(&tcp_sock, bp, out_buflen); if (n > 0) { out_buflen -= n; bp += n; } __tcp_poll(); } out_bufp = out_buf; out_buflen = 0; __tcp_drain(&tcp_sock); // Check interrupt flag if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) { CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); cyg_hal_user_break(0); }}static voidnet_io_putc(void* __ch_data, cyg_uint8 c){ static bool have_dollar, have_hash; static int hash_count; *out_bufp++ = c; if (c == '$') have_dollar = true; if (have_dollar && (c == '#')) { have_hash = true; hash_count = 0; } if ((++out_buflen == sizeof(out_buf)) || (have_hash && (++hash_count == 3))) { net_io_flush(); have_dollar = false; }}static voidnet_io_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len){ int old_console; old_console = start_console(); printf("%s.%d\n", __FUNCTION__, __LINE__); end_console(old_console);#if 0 CYGARC_HAL_SAVE_GP(); while(__len-- > 0) net_io_putc(__ch_data, *__buf++); CYGARC_HAL_RESTORE_GP();#endif}static voidnet_io_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len){ int old_console; old_console = start_console(); printf("%s.%d\n", __FUNCTION__, __LINE__); end_console(old_console);#if 0 CYGARC_HAL_SAVE_GP(); while(__len-- > 0) *__buf++ = net_io_getc(__ch_data); CYGARC_HAL_RESTORE_GP();#endif}static cyg_boolnet_io_getc_timeout(void* __ch_data, cyg_uint8* ch){ int delay_count; cyg_bool res; CYGARC_HAL_SAVE_GP(); net_io_flush(); // Make sure any output has been sent delay_count = _timeout * 10; // delay in .1 ms steps for(;;) { res = net_io_getc_nonblock(__ch_data, ch);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -