Python's a drop-in replacement for BASIC in the sense that
Optimus Prime is a drop-in replacement for a truck.
— Cory Dodt
There is no doubt, connectivity is vital for embedded devices. The new generation of microchips is powerful enough to host whatever you want. This is great and opens a lot of doors. But, we do have to keep in mind that 8-bit devices with several kilobytes of RAM are still very popular. Often, when it comes to porting from one of those powerful platforms to another weaker platform (e.g. more energy efficient) it becomes simple to see: Small devices can’t simply handle all that we want them to. But these are needed for embedded development. This is just one of the pitfalls to consider when embedding a web server. Let’s see what the others are:
1. Do NOT use Web server
No, this is not a joke. Before embedding web server make a pause and think: What am I trying to achieve? Do I need a web server? Do you really want to make a cool start page and host it on coin-sized device? The answer to the last question, is that it’s perhaps a little too soon for that. So instead of a web server, consider working with a simple TCP server or even TCP client.
In practice, it’s quite simple. If you need a connectivity library, choose the one that supports a variety of protocols and is able to work as both a client and a server. And stick to it.
In this article, I will use “Networking Library” instead of “Embedded Web Server”, just as a broader concept.
2 . Do NOT forget that a web server is not your end product.
Okay, maybe that’s a bit drastic. Let’s say usually a web server is not your end product. Nevertheless, it should be small and efficient. Ideally, you want it to be so light, that the rest of the team working on your project may not even know that you have added connectivity options.
There are some minimum requirements that your networking library must have. At the very least this includes features to turn on and off compile time, using preprocessor directives. If you decided to use a HTTP client, then don’t forget to turn off the rest of supported features. This could save some amount of flash and RAM space. That’s the same on some microcontrollers. The best piece of advice is to use the resources and features your product needs, not all the features your networking library requires.
3 . Do NOT use HTTP blindly
Yes, HTTP is the most popular protocol nowadays, but often, it is really heavy. Consider also that all text-protocols can be deal breakers. They are not efficient in terms of size and they are hard to parse. So what about other protocols? What about MQTT? What about CoAP? Or raw UDP? These might be much more suitable for your project. If you use the proper network library for your job, you’ll have dozens of options to choose the right protocol for your project.
Of course, there are a lot of situations, when you have to use HTTP. For example, if your device has to access resources which use HTTP only. However, if you want your device to do only one action, for example complete a temperature reading and send it every minute, then why not consider UDP instead? Using a raw UDP packet with one field may not be the sexiest option, but who cares when it simple to send and easy to parse?
4. Do NOT rely on Linux/Windows tests
Many embedded networking libraries and web servers are quite portable and work on desktop systems (Linux, Windows) as well. This is great when you are testing out your different options. It’s simpler to choose a library after testing on your computer.
Unfortunately, portable libraries use completely different network layers for different embedded platforms. This means that the test results from your desktop can be very different than the results from the actual device you want to implement on. Some networking libraries and embedded web server don’t support the same features on every platform. Ouch. And, do you remember about big and little endian? Not all networking libraries properly work on both models.
I like a lazy test as much as the next person. But, my advice here, do your final testing on your target device to avoid any bad surprises!
5. Do NOT allow unlimited connections
Most embedded devices are still constrained in terms of memory. Some devices are constrained in terms of sockets. So, don’t allow unlimited connections, it may lead a to lack of resources.
By the same token, a lot of hardware implementations of socket APIs (or similar) limit the use of sockets. For example Wiznet W5100 allows you to create four sockets. One of these will be used to listen for connections. So that leaves you with just 3. If you still need a server, it could leave you in a tight spot. Watch out for this as you choose your solution.
6. Do NOT allow your web server to use too much power
If your device is powered by a battery, don’t forget to limit the connection activity. WiFi is quite inefficient in power usage. So, plan your application to interact with the network as little as possible (flashback to earlier: what about client instead of server?).
But really, how can you make this happen in practice? For example, ESP8266 can go to light sleep and wake on timer. If you pool your network resources too often, the device never goes into sleep mode. Other networking libraries require internal pooling to run its tasks. If you put this on a separate timer, the device won’t sleep.
7. Do NOT forget, it’s still an embeddable product
If your networking library ports well, it may allow you to write and test a big amount of code in your usual IDE. Just remember, the final version will have to work on a small device and will be compiled with another compiler. Try to avoid malloc and friends. Malloc tends to return NULL quite soon, especially if all you have is 2Kb of memory.
This may be an obvious one, but you need to keep it in mind.
8. Do NOT use SSL – Unless you really need to
Yes, I know, this sounds impossible. Yes, I know, it sounds idiotic. Everybody uses SSL nowadays from the NSA, to the FBI and the Russians. But bear with me on this one.
SSL certificates require space on Flash and/or RAM. SSL calculations are very heavy for microchips: they take up a lot of time and energy. While it’s good if your specific device supports hardware SSL you often have to use software SSL too. In this case, ask yourself: Can I use an unprotected channel and save space?
It’s good to check your networking library to see if it’s able to use your chosen hardware implementation. Hardware implementations are very different and it can be quite difficult for library developers to support a lot of them.
9. Do NOT forget to KISS
Yes. Keep it simple, dude. Use the simplest protocols as you can. Think simpler than iPhone with 3Gb RAM and A10 Fusion CPU. Go as low as just an 8-bit CPU with 8Kb RAM. Need complicated logic? Well, you can put it on the server. Even Google works this way. Be like Google (in this case).
If you don’t keep it simple, the complicated logic is going to eat all of your device resources and battery power.
10. And do NOT despair!
I know that every time I port Mongoose Embedded Web Server to a new platform the last thing I need is 10 stupid pieces of advice. I generally want a hammer. But, then I think about it, go over the advice, take a few deep breaths, test and it works.
So get the right tool for your embedded project. Find the networking library or embedded web server that has the functionality you need, is light on its feet and delivers for you.