From 35c00972da41e12f4fb0590f4b4d45be91a31bfa Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 6 Aug 2014 11:59:41 -0600 Subject: NSH networking: There is now a configuration option that will bring up the network on an separate thread. Since the network bring-up is asynchronous, there are not serial console start-up delays due to the network negotiation time. --- apps/nshlib/Kconfig | 43 +++++++++++++++++++++++++++++ apps/nshlib/nsh.h | 12 ++++++++- apps/nshlib/nsh_init.c | 1 - apps/nshlib/nsh_netinit.c | 69 ++++++++++++++++++++++++++++++++++++++++++----- nuttx/TODO | 61 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 175 insertions(+), 11 deletions(-) diff --git a/apps/nshlib/Kconfig b/apps/nshlib/Kconfig index f710969f5..36839a736 100644 --- a/apps/nshlib/Kconfig +++ b/apps/nshlib/Kconfig @@ -777,6 +777,49 @@ config NSH_ARCHINIT menu "Networking Configuration" depends on NET +config NSH_NETINIT_THREAD + bool "Network initialization thread" + default n + depends on !DISABLE_PTHREAD + ---help--- + NSH is brought up through a series of sequential initialization + steps. This includes networking. If the network is available on + reset, then there is really no issue. Negotiating the link will + take only a second or so and the delay to the NSH prompt is + normally acceptable. + + But if there is no network connected, then the start-up delay can + be very long depending upon things like the particular PHY, driver + timeout delay times, and numbers of retries. A failed negotiation + can potentially take a very long time, perhaps as much as a + minute... Long enough that you might think that the board would + never come up! + + One solution is to enabled by this option. If NSH_NETINIT_THREAD + is selected, the network bring-up will all occur in parallel with + NSH on a separate thread. In this case, the NSH prompt will occur + immediately with the network becoming available some time layer (if + if all). This thread will terminate once it successfully initializes + the network + + NOTES: If no network is connected, the network bring-up will fail + and the network initialization thread will simply exit. There are + no retries and no mechanism to know if the network initialization + was successful. Furthermore, there is currently no support for + detecting loss of network connection. Lots of things to do! + +if NSH_NETINIT_THREAD + +config NSH_NETINIT_THREAD_STACKSIZE + int "Network initialization thread stack size" + default 1568 + +config NSH_NETINIT_THREAD_PRIORITY + int "Network initialization thread priority" + default 100 + +endif # NSH_NETINIT_THREAD + config NSH_DHCPC bool "Use DHCP to get IP address" default n diff --git a/apps/nshlib/nsh.h b/apps/nshlib/nsh.h index 1b76c19af..245690517 100644 --- a/apps/nshlib/nsh.h +++ b/apps/nshlib/nsh.h @@ -104,7 +104,9 @@ # define CONFIG_NSH_TMPDIR "/tmp" #endif -/* Networking support */ +/* Networking support. Make sure that all non-boolean configuration + * settings have some value. + */ #ifndef CONFIG_NSH_IPADDR # define CONFIG_NSH_IPADDR 0x0a000002 @@ -126,6 +128,14 @@ # define CONFIG_NSH_MACADDR 0x00e0deadbeef #endif +#ifndef CONFIG_NSH_NETINIT_THREAD_STACKSIZE +# define CONFIG_NSH_NETINIT_THREAD_STACKSIZE 1568 +#endif + +#ifndef CONFIG_NSH_NETINIT_THREAD_PRIORITY +# define CONFIG_NSH_NETINIT_THREAD_PRIORITY 100 +#endif + #ifndef CONFIG_NET # undef CONFIG_NSH_ARCHMAC #endif diff --git a/apps/nshlib/nsh_init.c b/apps/nshlib/nsh_init.c index 96dea72bc..c9b6a8578 100644 --- a/apps/nshlib/nsh_init.c +++ b/apps/nshlib/nsh_init.c @@ -101,4 +101,3 @@ void nsh_initialize(void) (void)nsh_netinit(); } - diff --git a/apps/nshlib/nsh_netinit.c b/apps/nshlib/nsh_netinit.c index c4e83d7e6..187a0bb2f 100644 --- a/apps/nshlib/nsh_netinit.c +++ b/apps/nshlib/nsh_netinit.c @@ -42,6 +42,7 @@ #include +#include #include #include @@ -95,18 +96,14 @@ ****************************************************************************/ /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nsh_netinit + * Name: nsh_netinit_thread * * Description: * Initialize the network per the selected NuttX configuration * ****************************************************************************/ -int nsh_netinit(void) +pthread_addr_t nsh_netinit_thread(pthread_addr_t arg) { struct in_addr addr; #if defined(CONFIG_NSH_DHCPC) @@ -116,6 +113,8 @@ int nsh_netinit(void) uint8_t mac[IFHWADDRLEN]; #endif + nvdbg("Entry\n"); + /* Many embedded network interfaces must have a software assigned MAC */ #if defined(CONFIG_NSH_NOMAC) && !defined(CONFIG_NET_SLIP) @@ -207,7 +206,65 @@ int nsh_netinit(void) } #endif + nvdbg("Exit\n"); return OK; } +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_netinit + * + * Description: + * Initialize the network per the selected NuttX configuration + * + ****************************************************************************/ + +int nsh_netinit(void) +{ +#ifdef CONFIG_NSH_NETINIT_THREAD + struct sched_param sparam; + pthread_attr_t attr; + pthread_t tid; + void *value; + int ret; + + /* Start the network initialization thread to perform the network bring-up + * asynchronously. + */ + + pthread_attr_init(&attr); + sparam.sched_priority = CONFIG_NSH_NETINIT_THREAD_PRIORITY; + (void)pthread_attr_setschedparam(&attr, &sparam); + (void)pthread_attr_setstacksize(&attr, CONFIG_NSH_NETINIT_THREAD_STACKSIZE); + + nvdbg("Starting netinit thread\n"); + ret = pthread_create(&tid, &attr, nsh_netinit_thread, NULL); + if (ret != OK) + { + ndbg("ERROR: Failed to create netinit thread: %d\n", ret); + (void)nsh_netinit_thread(NULL); + } + else + { + /* Detach the thread because we will not be joining to it */ + + (void)pthread_detach(tid); + + /* Name the thread */ + + pthread_setname_np(tid, "netinit"); + } + + return OK; + +#else + /* Perform network initialization sequentially */ + + (void)nsh_netinit_thread(NULL); +#endif +} + #endif /* CONFIG_NET */ diff --git a/nuttx/TODO b/nuttx/TODO index c280afef4..3e3c83e28 100644 --- a/nuttx/TODO +++ b/nuttx/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated June 24, 2014) +NuttX TODO List (Last updated August 6, 2014) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -49,7 +49,7 @@ nuttx/ apps/ (4) Network Utilities (apps/netutils/) - (3) NuttShell (NSH) (apps/nshlib) + (5) NuttShell (NSH) (apps/nshlib) (1) System libraries apps/system (apps/system) (5) Other Applications & Tests (apps/examples/) @@ -2324,10 +2324,65 @@ o NuttShell (NSH) (apps/nshlib) Priority: Low (multiple network interfaces not fully supported yet anyway). Title: ARP COMMAND - Description: Add an ARP command so that we can see the contents of the ARP table. + Description: Add an ARP command so that we can see and modify the contents of + the ARP table. Status: Open Priority: Low (enhancement) + Title: NETWORK BRINGUP + Description: If the network is available on reset, then there is really + no problem. Negotiating the link will take only a second or + so and the delay to the NSH prompt is normally acceptable. + + But if there is no network connected, then the start-up delay + can be very long depending upon things like the PHY, timeout + delay times, and numbers of retries. A failed negotiation + can take a very long time, perhaps as much as a minute... + Long enough that you would think that the board would never + come up. + + The problem is that all of the initialization is sequential: + NSH does not run until each sequential initialization step is + completed. + + There is an option enabled by CONFIG_NSH_NETINIT_THREAD that + will do the network bring-up asynchronously in parallel on + a separate thread. This eliminates the networking delay + altogether. The initial implementation, however, has some + limitations: + + - If no network is connected, the network bring-up will fail + and the network initialization thread will simply exit. + There are no retries and no mechanism to know if the network + initialization was successful. + + - Furthermore, there is currently no support for detecting loss + of network connection and recover of the connection (see the + next issue). + Status: Open + Priority: Medium, but certainly high if you plan to use the generic + NSH in a product with a network. + + Title: LOSS OF CONNECTION + Description: There is no logic in place no to detect that the network + connection has been lost (if the cable has been unplugged, + for example). And also no logic to bring the network back + up when the link can be re-established. + + This is normally done by catching a GPIO interrupt from a + PHY. This is logic outside of the Ethernet MAC driver + (although the Ethernet MAC driver would also have to + support the PHY operations to determine the link state). + So of the boards provide logic to connect to the PHY + interrupt. Like: + + xcpt_t sam_phyirq(int intf, xcpt_t irqhandler); + + But that interrupt is not used by anything now. + Status: Open + Priority: Medium. + + Status: Open o System libraries apps/system (apps/system) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3