📄 net_io.c
字号:
default:
break;
}
CYGARC_HAL_RESTORE_GP();
return ret;
}
static int
net_io_isr(void *__ch_data, int* __ctrlc,
CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
{
char ch;
CYGARC_HAL_SAVE_GP();
*__ctrlc = 0;
if (net_io_getc_nonblock(__ch_data, &ch)) {
if (ch == 0x03) {
*__ctrlc = 1;
}
}
CYGARC_HAL_RESTORE_GP();
return CYG_ISR_HANDLED;
}
// TEMP
int
start_console(void)
{
int cur_console =
CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
int i = 0;
if ( flash_get_config( "info_console_force", &i, CONFIG_BOOL) )
if ( i )
if ( ! flash_get_config( "info_console_number", &i, CONFIG_INT) )
i = 0; // the default, if that call failed.
if ( i )
CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
else
#endif
CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
return cur_console;
}
void
end_console(int old_console)
{
// Restore original console
CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
}
// TEMP
static void
net_io_revert_console(void)
{
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
console_selected = false;
#endif
CYGACC_CALL_IF_SET_CONSOLE_COMM(orig_console);
CYGACC_CALL_IF_SET_DEBUG_COMM(orig_debug);
console_echo = true;
}
static void
net_io_assume_console(void)
{
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
console_selected = true;
#endif
console_echo = false;
orig_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL);
orig_debug = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
CYGACC_CALL_IF_SET_DEBUG_COMM(TCP_CHANNEL);
}
static void
net_io_init(void)
{
static int init = 0;
if (!init) {
hal_virtual_comm_table_t* comm;
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
// Setup procs in the vector table
CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL);
comm = CYGACC_CALL_IF_CONSOLE_PROCS();
//CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
CYGACC_COMM_IF_WRITE_SET(*comm, net_io_write);
CYGACC_COMM_IF_READ_SET(*comm, net_io_read);
CYGACC_COMM_IF_PUTC_SET(*comm, net_io_putc);
CYGACC_COMM_IF_GETC_SET(*comm, net_io_getc);
CYGACC_COMM_IF_CONTROL_SET(*comm, net_io_control);
CYGACC_COMM_IF_DBG_ISR_SET(*comm, net_io_isr);
CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, net_io_getc_timeout);
// Disable interrupts via this interface to set static
// state into correct state.
net_io_control( comm, __COMMCTL_IRQ_DISABLE );
// Restore original console
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
init = 1;
gdb_active = false;
}
__tcp_listen(&tcp_sock, gdb_port);
state = tcp_sock.state;
#ifdef DEBUG_TCP
diag_printf("show tcp = %p\n", (void *)&show_tcp);
#endif
}
// Check for incoming TCP debug connection
void
net_io_test(bool is_idle)
{
if (!is_idle) return; // Only care about idle case
if (!have_net) return;
__tcp_poll();
if (state != tcp_sock.state) {
// Something has changed
if (tcp_sock.state == _ESTABLISHED) {
// A new connection has arrived
net_io_assume_console();
in_bufp = in_buf; in_buflen = 1; *in_bufp = '\r';
out_bufp = out_buf; out_buflen = 0;
}
if (tcp_sock.state == _CLOSED) {
net_io_init(); // Get ready for another connection
}
}
state = tcp_sock.state;
}
// This schedules the 'net_io_test()' function to be run by RedBoot's
// main command loop when idle (i.e. when no input arrives after some
// period of time).
RedBoot_idle(net_io_test, RedBoot_IDLE_NETIO);
//
// Network initialization
//
#include <cyg/io/eth/eth_drv.h>
#include <cyg/io/eth/netdev.h>
#include <cyg/hal/hal_tables.h>
// Define table boundaries
CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );
CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );
RedBoot_init(net_init, RedBoot_INIT_LAST);
static void
show_addrs(void)
{
diag_printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr));
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
diag_printf("/%s", inet_ntoa((in_addr_t *)&__local_ip_mask));
diag_printf(", Gateway: %s\n", inet_ntoa((in_addr_t *)&__local_ip_gate));
#else
diag_printf(", ");
#endif
diag_printf("Default server: %s", inet_ntoa(&my_bootp_info.bp_siaddr));
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
show_dns();
#endif
diag_printf("\n");
}
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
static void
flash_get_IP(char *id, ip_addr_t *val)
{
ip_addr_t my_ip;
int i;
if (flash_get_config(id, &my_ip, CONFIG_IP)) {
if (my_ip[0] != 0 || my_ip[1] != 0 ||
my_ip[2] != 0 || my_ip[3] != 0) {
// 'id' is set to something so let it override any static IP
for (i=0; i<4; i++)
(*val)[i] = my_ip[i];
}
}
}
#endif
static cyg_netdevtab_entry_t *
net_devtab_entry(unsigned index)
{
cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index];
if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__)
return NULL;
return t;
}
const char *
net_devname(unsigned index)
{
cyg_netdevtab_entry_t *t = net_devtab_entry(index);
if (t)
return t->name;
return NULL;
}
int
net_devindex(char *name)
{
const char *devname;
int index;
for (index = 0; (devname = net_devname(index)) != NULL; index++)
if (!strcmp(name, devname))
return index;
return -1;
}
static void
show_eth_info(void)
{
diag_printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
__local_enet_sc->dev_name,
__local_enet_addr[0],
__local_enet_addr[1],
__local_enet_addr[2],
__local_enet_addr[3],
__local_enet_addr[4],
__local_enet_addr[5]);
}
void
net_init(void)
{
cyg_netdevtab_entry_t *t;
unsigned index;
struct eth_drv_sc *primary_net = (struct eth_drv_sc *)0;
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
char *default_devname;
int default_index;
#endif
// Set defaults as appropriate
#ifdef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
use_bootp = false;
#else
use_bootp = true;
#endif
#ifdef CYGDBG_REDBOOT_NET_DEBUG
net_debug = true;
#else
net_debug = false;
#endif
gdb_port = CYGNUM_REDBOOT_NETWORKING_TCP_PORT;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
// Fetch values from saved config data, if available
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
flash_get_config("net_device", &default_devname, CONFIG_NETPORT);
#endif
flash_get_config("net_debug", &net_debug, CONFIG_BOOL);
flash_get_config("gdb_port", &gdb_port, CONFIG_INT);
flash_get_config("bootp", &use_bootp, CONFIG_BOOL);
if (!use_bootp) {
flash_get_IP("bootp_my_ip", &__local_ip_addr);
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
flash_get_IP("bootp_my_ip_mask", &__local_ip_mask);
flash_get_IP("bootp_my_gateway_ip", &__local_ip_gate);
#endif
}
#endif
# ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
// Don't override if the user has deliberately set something more
// verbose.
if (0 == cyg_io_eth_net_debug)
cyg_io_eth_net_debug = net_debug;
# endif
have_net = false;
// Make sure the recv buffers are set up
eth_drv_buffers_init();
__pktbuf_init();
// Initialize network device(s).
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
default_index = net_devindex(default_devname);
if (default_index < 0)
default_index = 0;
#endif
for (index = 0; (t = net_devtab_entry(index)) != NULL; index++) {
if (t->init(t)) {
t->status = CYG_NETDEVTAB_STATUS_AVAIL;
if (primary_net == (struct eth_drv_sc *)0) {
primary_net = __local_enet_sc;
}
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
if (index == default_index) {
primary_net = __local_enet_sc;
}
#endif
}
}
__local_enet_sc = primary_net;
if (!__local_enet_sc) {
diag_printf("No network interfaces found\n");
return;
}
// Initialize the network [if present]
if (use_bootp) {
if (__bootp_find_local_ip(&my_bootp_info) == 0) {
have_net = true;
} else {
// Is it an unset address, or has it been set to a static addr
if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
__local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) {
show_eth_info();
diag_printf("Can't get BOOTP info for device!\n");
} else {
diag_printf("Can't get BOOTP info, using default IP address\n");
have_net = true;
}
}
} else {
enet_addr_t enet_addr;
have_net = true; // Assume values in FLASH were OK
// Tell the world that we are using this fixed IP address
if (__arp_request((ip_addr_t *)__local_ip_addr, &enet_addr, 1) >= 0) {
diag_printf("Warning: IP address %s in use\n", inet_ntoa((in_addr_t *)&__local_ip_addr));
}
}
if (have_net) {
show_eth_info();
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
flash_get_IP("bootp_server_ip", (ip_addr_t *)&my_bootp_info.bp_siaddr);
#endif
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
redboot_dns_res_init();
#endif
show_addrs();
net_io_init();
}
}
static char usage[] = "[-l <local_ip_address>[/<mask_len>]] [-h <server_address>]";
// Exported CLI function
static void do_ip_addr(int argc, char *argv[]);
RedBoot_cmd("ip_address",
"Set/change IP addresses",
usage,
do_ip_addr
);
void
do_ip_addr(int argc, char *argv[])
{
struct option_info opts[3];
char *ip_addr, *host_addr;
bool ip_addr_set, host_addr_set;
struct sockaddr_in host;
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
char *dns_addr;
bool dns_addr_set;
#endif
int num_opts;
init_opts(&opts[0], 'l', true, OPTION_ARG_TYPE_STR,
(void *)&ip_addr, (bool *)&ip_addr_set, "local IP address");
init_opts(&opts[1], 'h', true, OPTION_ARG_TYPE_STR,
(void *)&host_addr, (bool *)&host_addr_set, "default server address");
num_opts = 2;
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
init_opts(&opts[2], 'd', true, OPTION_ARG_TYPE_STR,
(void *)&dns_addr, (bool *)&dns_addr_set, "DNS server address");
num_opts++;
#endif
CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options");
if (!scan_opts(argc, argv, 1, opts, num_opts, 0, 0, "")) {
return;
}
if (ip_addr_set) {
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
char *slash_pos;
/* see if the (optional) mask length was given */
if( (slash_pos = strchr(ip_addr, '/')) ) {
int mask_len;
unsigned long mask;
*slash_pos = '\0';
slash_pos++;
if( !parse_num(slash_pos, (unsigned long *)&mask_len, 0, 0) ||
mask_len <= 0 || mask_len > 32 ) {
diag_printf("Invalid mask length: %s\n", slash_pos);
return;
}
mask = htonl((0xffffffff << (32-mask_len))&0xffffffff);
memcpy(&__local_ip_mask, &mask, 4);
}
#endif
if (!_gethostbyname(ip_addr, (in_addr_t *)&host)) {
diag_printf("Invalid local IP address: %s\n", ip_addr);
return;
}
// Of course, each address goes in its own place :-)
memcpy(&__local_ip_addr, &host.sin_addr, sizeof(host.sin_addr));
}
if (host_addr_set) {
if (!_gethostbyname(host_addr, (in_addr_t *)&host)) {
diag_printf("Invalid server address: %s\n", host_addr);
return;
}
my_bootp_info.bp_siaddr = host.sin_addr;
}
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
if (dns_addr_set) {
set_dns(dns_addr);
}
#endif
show_addrs();
if (!have_net) {
have_net = true;
net_io_init();
}
}
// EOF net_io.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -