Now that we’ve got our physical layer complete, it’s time to start programming. Before we start writing any applications, however, we need firmware, the part of the device-end stack that serves as a bridge between hardware and software. Essentially, firmware is code that directly interfaces with hardware.
While every computer needs firmware, IoT devices pose a unique challenge. Every device is different. Between all the different connectivity options, types of controllers, and even 3D printed parts, we end up with unique hardware architectures that require unique firmware.
That’s why Very uses Nerves. This open-source platform is tailor-made for IoT because it offers unparalleled customizability. Every Nerves device boots into a BEAM Erlang virtual machine, but that’s where the similarities end. Developers can choose what bootloader to use, what parts of the Linux Kernel to utilize, and whether to run applications on bare metal or on top of a fuller operating system.
In truth, firmware actually includes an entire stack of technologies. What’s important to keep in mind, however, is that we package them up under a single roof with Nerves. Some of these technologies include file systems, drivers, and shell environments.
The top of the thing-end stack is where we tell our thing what to do. Software lets us say something as simple as “read this sensor” or “push this button,” or it can be as complex as defining communication protocols, running algorithms, or querying databases. Just like firmware, software contains a stack of its own, but this time we can break it down into three major categories.
At the bottom, we have programming languages that “allow us to give instructions in a language the computer understands.” By compiling down to binaries, they let us translate our own ideas into computable logic. Very has a few go-to programming languages that we use for device-end software development. This isn't a comprehensive list but provides a solid idea of where our focus lies.
First, we use Elixir. Optimized for IoT, Elixir enables us to create scalable applications that can simultaneously run many processes while also emphasizing simple, resilient code.
Another key device-end language we use is Python. A high-level, abstracted language, Python is today's most popular language due to its versatility and power. We primarily use it for applications, such as machine learning algorithms, that can’t be built on Elixir.
Finally, we also use C, a massively popular language designed for programming machines, for embedded development.
The second part of the software stack is libraries. Basically, libraries are pre-written code that we can mix, match, and build on top of to create applications. Awesome Elixir libraries include tools for everything from cryptography to geolocation to testing. Python also has a staggering number of libraries, and some of our favorites are in the PyTorch Ecosystem for deep learning.
The third and final layer of the software stack is the IoT application itself. Yup—we’ve finally arrived at our app! An application is a synthesis of everything that it sits on top of, and in many ways, it’s the reason we started building the device in the first place. Applications collect, process, and communicate data, they control input and output streams, and they are the easiest part of the stack to update or reconfigure.
Although the entire IoT stack needs to work together in harmony for best results, we also see a hierarchical structure emerge where higher layers depend upon the lower ones. Sure, the hardware depends on the software to tell it what to do, but the software needs hardware to even exist in the first place.
Because the stack contains so many interdependencies, we use an agile process to build and iterate upon our design. Of course, everything starts with hardware, but we won’t know which hardware to use if we don’t have a clear picture of the applications that we want to run.
The other takeaway is that the IoT device-end stack offers extreme flexibility. Device development gives us a great opportunity to select the exact technologies we’ll need to accomplish our goals without bringing on any extra baggage. The result is energy efficiency, a smaller attack surface, and dynamic functionality.
It’s how we create the right tool for the job.
So, are you getting excited for your next IoT project? Check out our guide to IoT development frameworks and best practices.