2009年2月15日 星期日

Implementing a processor-independent, battery-powered wireless mesh network

By David Ewing
Courtesy of Embedded.com
In many cases, it is required to add wireless capability to existing embedded systems. Often, in order to minimize costs, it is necessary to run the wireless software stack (and associated applications) on the same processor that drives the main system.

This can cause problems with conventional wireless implementations in which (a) the stack is closely tied to a particular microcontroller and (b) creating the wireless applications requires extensive C/C++ programming and embedded expertise.

This article describes an alternative approach that mitigates these problems. By providing the stack with an integrated Hardware Abstraction Layer (HAL), the body of the stack is isolated from any low-level "pin-twiddling" operations.

Also, by incorporating a Python virtual machine in the stack, applications can be quickly and easily created in the Python scripting language and (transparently to the user) compiled into machine-independent "byte code" that will run on any processor and that can be downloaded "over-the-air" into the wireless node(s).

Looking for an alternative approach
The world is currently seeing an exponential growth in the use of wireless networks for monitoring and control in consumer, commercial, industrial, and government markets. Uses range from building automation (lighting, heating, A/C) to industrial control and machine communication, to medical monitoring, to security applications, to home automation.

In many cases, it is required to add wireless capability to existing embedded systems. Often, in order to minimize costs, it is necessary to run the wireless software stack (and associated applications) on the same processor that drives the main system.

This can cause problems with conventional wireless implementations in which (a) the stack is closely tied to a particular microcontroller and (b) creating the wireless applications requires extensive C/C++ programming and embedded expertise.

This article describes an alternative approach that mitigates these problems. By providing the stack with an integrated Hardware Abstraction Layer (HAL), the body of the stack is isolated from any low-level "pin-twiddling" operations.

Also, by incorporating a Python virtual machine in the stack, applications can be quickly and easily created in the Python scripting language and (transparently to the user) compiled into machine-independent "byte code" that will run on any processor and that can be downloaded "over-the-air" into the wireless node(s).

What do you actually want to do?
A few years ago, the company for which I am VP of Engineering realized that the embedded world was poised to go wireless and that there was going to be a tremendous market in wireless monitoring and control network applications. At that time, the company, Synapse, was focused on sensor applications, so expanding our mission " and renaming ourselves to Synapse Wireless " was an obvious evolution.

We quickly realized that there were a variety of implementation scenarios depending on each customer's unique requirements. In order to provide a simple example, let's assume an existing system that includes a microcontroller that is used to monitor one or more sensors, accept user input, drive a display, and output signals via a wired connection (using RS232, for example) as illustrated in Figure 1 below.

Figure 1. Existing system with a wired connection to the outside world.

Assuming the creators of this system wish to augment their product with wireless capabilities, one scenario would be to simply modify their existing board to accept an off-the-shelf plug-in wireless module as illustrated in Figure 2 below.

Figure 2. Adding a plug-in module to provide a wireless connection to the outside world.

In addition to an on-board microcontroller (with timers, A/D converters etc.) and a radio frequency (RF) chip, the wireless module would also include some non-volatile memory containing the wireless protocol stack and user-created wireless applications.

Alternatively, high-volume and/or price-sensitive projects may require that the wireless functionality is implemented directly onto the motherboard as illustrated in Figure 3 below..

Figure 3. Running the wireless stack on the on-board microcontroller.

In this case, rather than having two processors (the microcontroller for the main system and the microcontroller on the wireless module), the RF PHY chip (along with any related RF components) would be mounted directly on the main circuit board, while the wireless stack and application software would be executed on the same microcontroller used to control the rest of the system.

Once a product has been equipped with wireless capability, the next step is to create and deploy any wireless applications; that is, the programs that monitor the sensor inputs, make decisions, and drive the actuator outputs that interface to the real-world. These applications also instigate the wireless transmission of commands and data (via requests to the stack) and respond to incoming commands and data (received and processed by the stack).

So, from our perspective, the problem was multifaceted. With regard to the creators of embedded systems, we wanted to be in a position to provide (a) off-the-shelf wireless modules and (b) a processor-independent wireless stack that could be easily ported onto existing microcontrollers. Meanwhile, in the case of the end users, we wanted to provide an environment that allowed applications to be created, deployed, and debugged quickly and efficiently.

Surely this wasn't too much to ask ... was it?

A square peg in a round hole...
Our first thought was that we would be able to purchase an existing, off-the-shelf software stack from someone, and then customize it to our requirements.

So, we set out to see what was available that would meet our specifications while giving us the best combination of cost, reliability, ease-of-use, and so forth. However, it didn't take us long to discover that existing solutions were lacking in just about every department.

As a starting point, we were looking for processor-independence to allow us to accommodate the needs of multiple users, each of whom might require that the stack ran on a specific microcontroller. We did find several companies who were providing software stacks that they had implemented on the microcontroller of their choice, but these microcontrollers were not necessarily the ones required by our customers.

We also discovered that re-porting one of these existing stacks to a different microcontroller would be a non-trivial task, because some services in the stack need access to the underlying hardware (timers, input/output pins, etc.), and this access was typically hard-coded into the stack. This would have made every new port a resource-intensive and time-consuming challenge.

Another problem we discovered was the somewhat limited routing capabilities associated with existing stacks. In the case of mesh routing, for example, network nodes that are in direct range of each other will communicate directly; when nodes are not in direct radio range, intermediate nodes will automatically forward any messages to their intended destinations. In a robust mesh routing implementation, if a node catastrophically fails for any reason, other nodes should automatically route signals around the failed node.

Now, our initial impression was that all of the end devices " that is, the nodes with the sensors and actuators that interface with the real world " in the network would be able to act as routers to forward traffic through the network. In reality, however, we discovered that the end devices and routers in a typical network are implemented as distinct nodes as illustrated in Figure 4 below.

(In the real world, each router would communicate with multiple end devices, and each end device can handle multiple sensors and actuators, but this simple representation will serve our purposes here.)

Figure 4. The end devices and routers in a typical network are implemented as distinct nodes

The point is that the way the off-the-shelf stacks we looked at operated, the end devices couldn't talk to each other; instead, each end device had to communicate with a local router

In turn, this meant that if a router failed, any end devices associated with the failed node had to be able to access another router in close enough proximity, which means that the routers would need to be located artificially close together. To some extent, this sort of defeats the point of mesh routing in the first place.

But wait, there's more! In some wireless network deployments, it is possible for all of the physical nodes to be externally powered ("plugged into a wall socket"). In this case, power consumption is not a problem and all of the nodes can be active " "talking"/transmitting and/or "listening"/receiving " all of the time.

In many environments, however, it is necessary for the nodes to be powered by batteries, in which case power consumption can be a significant problem. Even in the case of a low-power wireless module, an active module will consume an average of 50 milliamps (mA). When powered by AA batteries capable of supplying say 2,500 milliamp-hours (mAh), this means that a node can stay active for 2,500 / 50 = 50 hours, which is a little over two days.

This is simply not acceptable in terms of resource requirements (someone changing the batteries) and expense (batteries aren't cheap) for the vast majority of installations, especially in the case of networks involving hundreds or thousands of wireless nodes. The solution is for the nodes to alternate between being "awake" for a short amount of time and then entering a "sleep mode" in which they consume dramatically less power.

Once again we ran into a problem with the existing stack implementations we evaluated. Although it was possible to power-down the end devices, the router nodes had to stay active all of the time as illustrated in Figure 5 below. Having to maintain these nodes on external power sort of defeats the point of the exercise in the first place.

Figure 5. A traditional wireless network with its end devices in sleep mode (but its routers have to remain active on external power).

Last but certainly not least, we started to consider the creation, deployment, and debugging of the wireless applications that would sit on top of the stack. In order to experiment, I purchased one of the "easy-to-use, off-the-shelf" wireless development kit's I'd read so much about to play with. This kit comprised a coordinator, a router, and a couple of end devices, each of which boasted an 8051-based microcontroller and non-volatile memory containing the stack.

But how were we to create test applications? I called the kit's technical support, only to discover that it was my responsibility to purchase a C compiler and/or assembler for the 8051.

When we finally did get to start playing with applications, we discovered that it required a lot of wireless and embedded programming expertise. Once we finally had an executable, we had to physically connect a dongle to download the application it to the target node, and then we found ourselves in the mire of debugging the application.

At this point I decided that I was less than happy. Using an existing stack as a starting point was too much like trying to force a square peg into a round hole. The vast majority of our target customers simply did not have sufficient wireless knowledge or embedded programming expertise to make this work. If we were to avoid sinking into a morass of support issues, we needed to come up with a better solution...

Creating wireless networks in a SNAP
Eventually, we decided to create our own "lean-and-mean" wireless stack from the ground up, resulting in Synapse's Wireless Mesh Network Protocol (SNAP). A high-level view of the SNAP stack is illustrated in Figure 6 below. In addition to the IEEE 802.15.4 physical layer (PHY), which is not shown here for reasons of simplicity, the protocol stack also employs the industry-standard 802.15.4 packet interface.

Figure 6. The SNAP software stack.

This high-performance stack is designed to run efficiently on cost-effective 8-bit microprocessors. Even though it provides full mesh capabilities, our software protocol stack has a very small memory footprint of only 40 KB, thereby leaving more space for user applications.

This is a real consideration in cost-conscious deployment scenarios, because conventional stacks typically consume 50 to 60 KB or more. This means that network nodes running conventional stacks have to move from a 64 KB memory device to a more-expensive 128 KB part in order to provide enough space to store the users' applications.

Written in optimized, portable, industry-standard ANSI C code, the software stack has been designed from the ground up for portability. In particular, the Hardware Abstraction Layer (HAL) provides a layer of abstraction between the main body of the software stack and the physical world, including the specifics of accessing registers in the processor, reading/writing values to Input/Output (I/O) pins, controlling Analog-to-Digital (A/D) converters, and so forth. This means that the process of porting the stack to a new processor requires modifications only to the "thin slice" of the HAL.

With regard to implementing, deploying, and commissioning a network, we wanted to make things as easy as possible. As a result, a protocol enabled network (which can comprise tens of thousands of nodes) is self-forming (the network establishes itself); when a new node is powered-up it is automatically integrated into the network.

Nodes are also instant-on; as soon as a node is powered-up, it becomes fully operational in a fraction of a second. Furthermore, such networks are self-healing; if a node catastrophically fails for any reason, other nodes will automatically route signals around the failed node.

Also of interest is the fact that all of the nodes are peer-to-peer, which means there is no need for special coordinator or router nodes as illustrated in Figure 7 below. In the case of the administrator software running on a PC, whichever wireless node is connected to the PC automatically becomes the "bridge" node into the network.

Figure 7. All of the nodes in a SNAP-based network are peer-to-peer.

Of particular interest in the case of low-power applications is the fact that all of the nodes in a SNAP network can be automatically put to sleep and awakened synchronously as illustrated in Figure 8 below.

Depending on the requirements of the target application, the resulting "sleepy mesh" can extend the battery life of each node to the shelf life of the batteries while still supporting full mesh routing!

Figure 8. A SNAP-based "sleepy mesh" in its sleep mode.

Thus far, we have addressed the needs of the creators of embedded wireless products, but what about the folks who wish to build wireless applications? We decided that, in order to make wireless technology available to a broader audience, we needed to make it truly easy to create, deploy, and debug applications.

Thus, we created a software tool called Portal, which runs on a PC and can be used to develop applications and deploy them "over-the-air" to protocol enabled-based wireless nodes. Portal can also be used to configure and manage the network as required, and it can provide additional functions such as data logging, event monitoring, and debugging.

Small, fast, and extremely efficient, Portal is seen by the network as "just another node". The PC running Portal may be physically connected to any of our wireless nodes, which subsequently acts as a bridge into the network.

User applications are created in the form of easy-to-understand Python scripts, which are composed of one or more functions. The combination of our software protocol stack and Python is known as "SNAPpy." Any such function in any node on the network can be called from Portal or from any other node on the network. Similarly, any node on the network can invoke such a script running on Portal.

Such enabled applications are automatically translated into what is known as "byte code" and are then downloaded over-the-air into the wireless network nodes. As was shown in Figure 6, the software stack includes a Python Virtual Machine, which executes the byte codes forming the applications.

This provides extreme portability, because the Virtual Machine provides a layer of abstraction that separates the applications from the physical hardware. This means that an application executable will immediately run on any processor without requiring any modification or re-compilation.

Most networking environments require the use of multiple applications to perform tasks such as editing code, listing the nodes in the mesh, accessing and indicating the status of nodes, and so forth. By comparison, Portal provides all of these functions in a single, intuitive, easy-to-use interface.

For example, clicking on a node in Portal displays the application script that is running on that node. The user can then call up the source for that script, make a modification, and upload the new code into the target node over-the-air " all in a matter of seconds. Furthermore, debugging can be performed by means of 'print' statements in the code, which provides almost instantaneous edit-compile-download-run-debug cycles.

David Ewing is Vice President of Engineering for Synapse Wireless Inc. and brings over 18 years of professional expertise in building and managing software teams. He can be contacted at David.Ewing@synapse-wireless.com.


沒有留言:

張貼留言