In the past, if the network were not connected when you brought up NuttX, two bad things could happen:
- It could take a very long time for the NSH prompt to come up because of the sequential initialization. This happens when, for example, the network cable is not connected. And,
- After NuttX came up, installing the network cable would not give you a network. The only way that you could recover networking was to install the cable and reset the board.
But no more. Network link management capability has been added to NSH.
First, you can very simply enable a feature that moves network initialization to a separate thread so that it is no longer done sequentially. Rather, the network bringup occurs asynchronously and the NSH prompt appears immediately (although the network may not be available until a little later). That feature is enabled simply with the following setting and is the first prerequisite for the full NSH link management feature:
CONFIG_NSH_NETINIT_THREAD. See the help text in the Kconfig file for this option (
apps/nshlib/Kconfig). There is a lot more information about this setting there.
The logic that implements the NSH network management is the file
apps/nshlib/nsh_netinit.c. The behavior of the logic in that file depends on several configuration settings. First, there are a settings that are additional prerequisites to support the feature:
CONFIG_NETDEV_PHY_IOCTL. Enable PHY IOCTL commands in the Ethernet device driver. Special IOCTL commands must be provided by the Ethernet driver to support certain PHY operations that will be needed for link management. There operations are not complex and are implemented for the Atmel SAM4/4 and SAMA5 families and also for the STMicro STM32. See
CONFIG_ARCH_PHY_INTERRUPT. This is not a user selectable option. Rather, it is set when you select a board that supports PHY interrupts. In most architectures, the PHY interrupt is not associated with the Ethernet driver at all. Rather, the PHY interrupt is provided via some board-specific GPIO and the board-specific logic must provide support for that GPIO interrupt. To do this, the board logic must do two things: (1) It must provide the function
arch_phy_irq()as described and prototyped in the
nuttx/include/nuttx/arch.h, and (2) it must select
CONFIG_ARCH_PHY_INTERRUPTin the board configuration file to advertise that it supports
arch_phy_irq(). Examples can be found at
- And a few other things: UDP support is required (
CONFIG_NET_UDP) and signals must not be disabled (
Then given all of these prerequisites you can enable the NSH network management on the NSH network intialization with these additonal options:
CONFIG_NSH_NETINIT_MONITOR. By default the net initialization thread will bring-up the network (or fail trying) then exit, freeing all of the resources that it required. If this option is selected, however, then the network initialization thread will persist forever; it will monitor the network status. In the event that the network goes down (for example, if a cable is removed), then the the thread will monitor the link status and attempt to bring the network back up. In this case the resources required for network initialization are never released.
If the network monitor is selected, then some additional options will control its behavior:
CONFIG_NSH_NETINIT_SIGNO. The network monitor logic will receive signals when there is any change in the link status. This setting may be used to customize that signal number in order to avoid conflicts.
CONFIG_NSH_NETINIT_RETRYMSEC. When the network is down, the initialization thread will periodically try to bring the network up. This can be a time consuming operation so is done only periodically with that period specified by this selection in milliseconds.
CONFIG_NSH_NETINIT_THREAD_STACKSIZE. Network initialization thread stack size.
CONFIG_NSH_NETINIT_THREAD_PRIORITY. Network initialization thread priority.
There is a summary of the operation of the NSH management thread.
- During initialization, the thread will open a UDP socket for performing IOCTLs and it will connect a signal handler.
- It will than enter a loop. At the top of of the loop, it will register (or perhaps re-register) to get signals when the PHY asserts a link up or link down interrupt. This has to be done repeatedly because the notification disarms after each PHY interrupt.
- It will then read the link status from the PHY and also from Ethernet device. It the do not agree, then the network monitor will use the take the Ethernet driver up or down to match the state of the network. So if the network is lost, the monitor will bring the Ethernet driver down; if the network is reagained, then the monitor will bring the Ethernet driver up and re-establish the connection.
- If the PHY and the Ethernet driver are in agreement about the link state, then nothing is done.
- At the bottom of the loop, the network monitor waits for a PHY interrupt or a timeout. When either occurs, it goes back to the top of the loop and does all of this again.
- If a PHY interrupt occurs, a signal is delivered to the task and caught by the network monitor signal handler. It posts and semaphore to immediately re-awaken the network montior from its wait.