⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_io.c

📁 redboot 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      net/net_io.c////      Stand-alone network logical I/O support for RedBoot////==========================================================================//####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// Date:         2000-07-14// Purpose:      // Description:  //              // This code is part of RedBoot (tm).////####DESCRIPTIONEND####////==========================================================================#include <redboot.h>#include <cyg/io/eth/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,                      CYGNUM_REDBOOT_NETWORKING_TCP_PORT    );RedBoot_config_option("Network debug at boot time",                       net_debug,                       ALWAYS_ENABLED, true,                      CONFIG_BOOL,                      false    );// 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,                      true    );RedBoot_config_option("Local IP address",                      bootp_my_ip,                      "bootp", false,                      CONFIG_IP,                      0    );#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAYRedBoot_config_option("Local IP address mask",                      bootp_my_ip_mask,                      "bootp", false,                      CONFIG_IP,                      0    );RedBoot_config_option("Gateway IP address",                      bootp_my_gateway_ip,                      "bootp", false,                      CONFIG_IP,                      0    );#endifRedBoot_config_option("Default server IP address",                      bootp_server_ip,                      "bootp", false,                      CONFIG_IP,                      0    );// Note: the following options are related too.RedBoot_config_option("Force console for special debug messages",                      info_console_force,                       ALWAYS_ENABLED, true,                      CONFIG_BOOL,                      false    );RedBoot_config_option("Console number for special debug messages",                      info_console_number,                       "info_console_force", true,                      CONFIG_INT,                      0    );#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[64];static unsigned char *in_bufp;static int out_buflen = 0;static unsigned char out_buf[1024];static unsigned char *out_bufp;static bool flush_output_lines = false;// Functions in this modulestatic void net_io_flush(void);static void net_io_revert_console(void);static void net_io_putc(void*, cyg_uint8);// Special characters used by Telnet - must be interpretted here#define TELNET_IAC    0xFF // Interpret as command (escape)#define TELNET_IP     0xF4 // Interrupt process#define TELNET_WONT   0xFC // I Won't do it#define TELNET_DO     0xFD // Will you XXX#define TELNET_TM     0x06 // Time marker (special DO/WONT after IP)static cyg_bool_net_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_sock.rxcnt == 0) {                __tcp_close(&tcp_sock);                return false;            }        }        if (tcp_sock.state == _CLOSED) {            // The connection is gone            net_io_revert_console();            *ch = '\n';            return true;        }        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();              diag_printf("%s:%d\n", __FUNCTION__, __LINE__);              diag_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_boolnet_io_getc_nonblock(void* __ch_data, cyg_uint8* ch){    cyg_uint8 esc;    if (!_net_io_getc_nonblock(__ch_data, ch))        return false;    if (gdb_active || *ch != TELNET_IAC)        return true;    // Telnet escape - need to read/handle more    while (!_net_io_getc_nonblock(__ch_data, &esc)) ;    switch (esc) {    case TELNET_IAC:        // The other special case - escaped escape        return true;    case TELNET_IP:        // Special case for ^C == Interrupt Process        *ch = 0x03;          // Just in case the other end needs synchronizing        net_io_putc(__ch_data, TELNET_IAC);        net_io_putc(__ch_data, TELNET_WONT);        net_io_putc(__ch_data, TELNET_TM);        net_io_flush();        return true;    case TELNET_DO:        // Telnet DO option        while (!_net_io_getc_nonblock(__ch_data, &esc)) ;                        // Respond with WONT option        net_io_putc(__ch_data, TELNET_IAC);        net_io_putc(__ch_data, TELNET_WONT);        net_io_putc(__ch_data, esc);        return false;  // Ignore this whole thing!    default:        return false;    }}static cyg_uint8net_io_getc(void* __ch_data){    cyg_uint8 ch;    int idle_timeout = 10;  // 10ms    CYGARC_HAL_SAVE_GP();    while (true) {        if (net_io_getc_nonblock(__ch_data, &ch)) break;        if (--idle_timeout == 0) {            net_io_flush();            idle_timeout = 10;        }    }    CYGARC_HAL_RESTORE_GP();    return ch;}static voidnet_io_flush(void){    int n;    char *bp = out_buf;#ifdef DEBUG_TCP    if (show_tcp) {        int old_console;        old_console = start_console();          diag_printf("%s.%d\n", __FUNCTION__, __LINE__);        diag_dump_buf(out_buf, out_buflen);          end_console(old_console);    }#endif // SHOW_TCP    n = __tcp_write_block(&tcp_sock, bp, out_buflen);    if (n < 0) {        // The connection is gone!        net_io_revert_console();    } else {        out_buflen -= n;        bp += n;    }    out_bufp = out_buf;  out_buflen = 0;    // 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;    CYGARC_HAL_SAVE_GP();    *out_bufp++ = c;    if (c == '$') have_dollar = true;    if (have_dollar && (c == '#')) {        have_hash = true;        hash_count = 0;    }    if ((++out_buflen == sizeof(out_buf)) ||        (flush_output_lines && c == '\n') ||        (have_hash && (++hash_count == 3))) {        net_io_flush();        have_dollar = false;    }    CYGARC_HAL_RESTORE_GP();}static voidnet_io_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len){    int old_console;    old_console = start_console();    diag_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();    diag_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;    for(;;) {        res = net_io_getc_nonblock(__ch_data, ch);        if (res || 0 == delay_count--)            break;    }    CYGARC_HAL_RESTORE_GP();    return res;}static intnet_io_control(void *__ch_data, __comm_control_cmd_t __func, ...){    static int vector = 0;    int ret = 0;    static int irq_state = 0;    CYGARC_HAL_SAVE_GP();    switch (__func) {    case __COMMCTL_IRQ_ENABLE:        irq_state = 1;        if (vector == 0) {            vector = eth_drv_int_vector();        }        HAL_INTERRUPT_UNMASK(vector);         break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -