When you think of inter-process communication (IPC) on an embedded Linux system what are the first couple of IPC mechanisms that come to mind? Signals, pipes, message queues, shared memory and sockets are some of the ones that traditionally pop up first. What about the Message Queue Telemetry Transport (MQTT) protocol? As it turns out, MQTT can do a great job beaming your messages from one process to another. If you find that you’re in the daunting position of architecting a complex embedded Linux system that’s also Internet of Things (IoT) capable, read on; you might learn something cool that takes a few more items off of your ever growing to-do list.
Before we delve more into why it’s so awesome, we should probably talk a little about what MQTT is. MQTT is a very lightweight publish/subscribe type protocol that is a natural fit for the Internet of Things. It was designed to minimize the amount of processing power required by end devices while also ensuring reliability on even the flakiest of networks. It is built to be used on top of TCP/IP so if you’re concerned about security, SSL is there to come to your rescue.
The backbone of the MQTT protocol is the message broker. It makes sure that all messages are routed to interested clients, using the message topic as the filter. This way a client is able to publish a single message to the message broker and the broker will then handle passing that message along to all of the clients that are subscribed to that specific topic. Wildcards are also supported in the message topics if you feel like getting a little crazy.
In a typical IoT use case, both your Web backend and your edge devices implement a MQTT Client. You then must either pay for a hosted, scalable message broker service like CloudMQTT, or host one yourself using an Open Source broker like Mosquitto. For our embedded Linux IPC use case the principles are the same, but instead of backend-to-device communication through the broker we have process-to-process communication through the broker. Once we included Mosquitto in our Linux build and found C/C++ MQTT clients for our applications we were off to the races.
Testing, testing and more testing… In my opinion, this is by far the largest advantage of designing your system with MQTT as the IPC mechanism. When you develop applications for an embedded Linux system, you typically start writing and testing them in a Linux Virtual Machine (VM); the ability to do so is part of what makes running Linux on an embedded target so enticing. If you can separate different functional pieces of your system into multiple apps, you can develop and test each app individually by running the Mosquitto broker in your VM and writing a test app for each. It is super quick to get something up and running using Python, and using this type of test framework during early development will bring you that warm fuzzy feeling down the road that all engineers long for.
Another great thing about MQTT is you have the ability to use JSON or XML for your message format if you like. This is incredibly useful for debugging communications because you can just log all of the MQTT messages at the broker and clearly see where you are going wrong, without cluttering your code with prints.
In most embedded systems, you need to communicate over a serial bus like CAN, SPI, or I2C in order to talk to the various peripherals. We’ve found that the best way to handle this when you’re using MQTT for your internal communication is to write a peripheral Gateway app for each serial interface. For example, the system that we are working on has an embedded controller on the CAN bus so we wrote a CAN to MQTT Gateway app in C. This allowed us to take advantage of C’s ability to pack/unpack binary data while also having a higher-level QT app to determine what to do with the data and to display it appropriately.
In this type of project where the edge device itself is fairly complex, on top of the fact that it needs to connect to the Internet, it is crucial that you design the edge device from the start with networking in mind. If you decide to use this type of architecture you are able to focus on getting the edge device working first, knowing all the while that once you start networking it will be as simple as opening an external MQTT port and adding a few extra callbacks to your applications.
When working on any sort of application, especially if it involves a UI, being able to quickly turn ideas into prototypes for the customer to look at it is very important. Embedded software traditionally does not lend itself well to rapid prototyping, but using MQTT for IPC definitely is a large step in the right direction. We’ve found it to be incredibly quick and easy to implement new features, and even whole new applications to support these features, using this kind of architecture. This drastically reduced the amount of time it took from feature inception to implementation, which went a long way towards keeping our customer happy.
If you are especially resource constrained, then MQTT is probably not a great choice for IPC. Many other IPC mechanisms require less processing overhead, especially since most do not require a local server (the message broker) to be running in order to use them. However, as silicon gets much more powerful and cost-effective I think that this will continue to become less of a concern, especially when you consider the large NRE savings to be had from using something like MQTT.
Do you enjoy manipulating strings in C? I didn’t think so; I’m not sure anyone does. When you use a text based message format, like JSON, inside of your MQTT messages, it can be kind of a pain to parse them in your C peripheral Gateway apps. We used an Open Source JSON library for C called jansson, which helped ease the pain quite a bit. It still wasn’t great, though, and I think if I could do it over I’d use C++ for the Gateway apps to get a little more help handling all the strings. The benefits of being able to easily print and read all of your internal messages still made it worthwhile, though.
I think it’s pretty clear that for using MQTT for IPC in IoT, the pros far outweigh the cons. We were a little leery about heading down this path at first, but once we got into the swing of things we were able to come up with a really cool design in not a lot of time. If this sounds like something that might work for you, give it a shot!