Understanding The imp API’s Device Restart Options
The imp API provides a number of ways to cause an imp to restart through application code. This guide looks at each of these methods to help you decide which to use in a given case. Your code may include any or all of these methods as determined by the needs of the application and the imp on which the code is running.
Before looking at each of the available restart methods, let’s review what normally happens to an imp after it is physically power-cycled. This action has the effect of completely resetting the hardware and software, in particular:
Connections to the impCloud require DHCP negotiation via the local router (unless the imp has been configured to use a static IP), and the exchange and verification of certificates between the imp and the impCloud. This adds a necessary latency to the start of application.
This is called a cold boot and its flow is indicated on the imp Network State Diagram via the Cold Start event. The flow outlined above assumes that the device has already been activated, ie. an end-user has provided the unit with network access credentials, if required, and enrolled the device into the impCloud. Devices without WiFi credentials, for example, will keep BlinkUp activated and signalled on the status LED. Devices which have no Squirrel (new Development Devices and Production Devices set to download their application code after activation) will not start the Squirrel VM at this point.
The first software-controlled restart method is to call server.sleepfor() or imp.deepsleepfor(). These calls both put the imp into a deep sleep state with a timer set to wake them after a supplied duration, provided as the functions’ argument. While this sleep period is typically of significant duration, by passing in zero as their sole argument, these calls can be used to cause an immediate restart, ie:
server.sleepfor(0);
or
imp.deepsleepfor(O);
These calls differ in that the former includes an implicit call to server.flush() to ensure that any messages in the transmit queue are sent before the imp sleeps; if you call imp.deepsleepfor() without previously calling server.flush() messages in the transmit queue, if any, will be lost, but this means the imp enters deep sleep more quickly, which may be advantageous for some applications.
When the imp awakes, all pins except any that have been been previously configured as a Zombie PWM return to their default states (tristated, except for some imp005 pins whose default state is different, see its pin mux page). In addition:
In this regard, this restart closely resembles a cold boot — other than the fact that the imp does not connect to the impCloud immediately. On the Network State Diagram this is the Warm Start point.
The imp will connect to the server as soon as Squirrel attempts to contact the device’s agent (ie. by agent.send()) or makes some other server-oriented call, such as server.log() or server.connect(). The device will attempt to connect outside of Squirrel control if an exception is thrown.
This method is the traditional method of triggering a restart, but is not available to applications running on the imp005, which does not support deep sleep, or on devices which lack deep sleep because their imp003 or imp004m module is not connected to a 32kHz crystal. For these devices, impOS 38 adds the following method.
This call closely resembles the use of server.sleepfor(0)
and imp.deepsleepfor(0)
to invoke an immediate restart, with one crucial difference: it causes the imp to follow the Cold Start path in the Network State Diagram. All pins except any that have been been previously configured as a Zombie PWM return to their default states (tristated, except for some imp005 pins whose default state is different, see its pin mux page). In addition:
This approach has the additional impact that the imp performs checks for new Squirrel code and impOS updates, which the Warm Start path does not include (unless a Squirrel error subsequently triggers one).
In addition, imp.reset() is available to imps which are not connected to a 32kHz crystal, ie. those which cannot deep sleep. This includes the imp005, for which server.sleepfor() and imp.deepsleepfor() have been disabled and therefore cannot be called.
This call causes the imp’s current Squirrel Virtual Machine to be taken down and re-instantiated. This action has the effect of completely resetting the application software — your Squirrel code runs afresh — and all pins except any that have been configured as a Zombie PWM return to their default states (tristated, except for some imp005 pins whose default state is different, see its pin mux page). However:
As such server.restart() is intended solely to be used to restart Squirrel, primarily in response to a message from the impCloud that fresh Squirrel and/or an impOS update is available; restarting Squirrel immediately causes such updates to be retrieved and installed — without the need to first boot the hardware and re-establish the network connection. This is part of impOS’ polite deployment mechanism.
You should know, however, that an impOS upgrade will trigger a warm boot after the update has been installed. Updating Squirrel simply restarts the VM.
This is the fastest means to restart an application as it does not cause the imp’s connection to be broken then re-established (unless it actions an impOS update) but it does not reset hardware.
This is a special case since it is not under the control of the Squirrel application code, but is included here for completeness. In this case, an operator uses the impCentral™ web app (or another impCentral API-based tool) to cause devices to restart. Such a command can also reach multiple devices if it is made to a Device Group rather than to a specific device. Restarts may be forced (the device(s) must restart) or conditional (device(s) restart only if are running application code that is older than the current minimum supported deployment).
The restart is essentially an externally triggered call to server.restart() and has the effect of completely resetting the software — your Squirrel code runs afresh — but has no impact on the hardware.
Which of the above methods you apply should be determined by why you need the device to restart. You may of course use multiple calls, depending on circumstance, eg. server.restart() in your polite deployment handler and imp.reset() in the code you have written to process a reset command issued by the end-user.
imp API Method | Resets Connection | Requires Manual Reconnection | Resets Application | Resets GPIO |
---|---|---|---|---|
imp.reset() | ✓ | ✕ | ✓ | ✓ |
server.restart() | ✕ | ✕ | ✓ | ✓ |
server.sleepfor(0) | ✓ | ✓ | ✓ | ✓ |