Microcontrollers are great at performing hardware related tasks in real time. They usually have a lot of flexibility when it comes to managing and customizing hardware peripherals (like I2C, SPI, ADC etc.) and are also simply irreplaceable when it comes to timing sensitive software tasks.
However, when it comes to a few computationally intensive tasks and complex devices, it may be easier to rely on an external co-processor. An Embedded Linux Device with a relatively powerful processor can fill this role.
Small Embedded GNU/Linux devices have become increasingly popular ever since the launch of devices like the Gumstix, Beaglebone and the Raspberry Pi. A subset of these devices come in compact modules that can be easily incorporated on a custom PCB without taking up too much space. Since almost all of these devices support full-fledged Linux distributions like Debian, it becomes extremely easy to leverage and install software packages that are already available to implement certain features or vastly reduce time for application development. Even if a package is not readily available, the source might be and it is usually straight-forward to compile natively or cross-compile to the target platform. These devices also offer a limited number of hardware interfaces (GPIO, USB, HDMI, etc.) with pre-existing drivers that can also be used.
Either the MCU or the Embedded Linux Device can perform the primary role, the eventual goal is to accomplish software and hardware feature completeness in the most efficient manner. Some setup examples include:
- The Linux Device runs most of the application code, device drivers are exclusively on the MCU
- The Linux Device runs only performs computationally intensive tasks, application and device driver firmware resides on the MCU
The devices can exchange information using serial communication to retrieve sensor information and also control outputs. If the application is written on a Linux Device, you are no longer limited to using C, but high-level languages like Python, C++, Go or even Java can also be used which will allow the easy import of existing software modules to shorten development time.
A few examples of tasks which the Linux Device can perform include:
- Video/Audio Capture and Processing
- Driving a GUI on a High Definition Display
- Web Server or Client with full-fledged security features
- Driving a USB Peripheral Device
- Push Firmware Updates or Configuration Information to the MCU using a serial bootloader
A few examples of tasks which the MCU is better suited to perform include:
- Custom Single-Wire Interfaces
- PWM output control: Motor Control, Lighting etc.
- Interrupt driven routines
An available Serial (UART) interface on the Linux device and the MCU should each be dedicated for communication. Additionally, if the MCU has a bootloader available, it could be useful to ensure that available on the MCU is also an interface accessible by the bootloader to receive firmware updates. The underlying protocol over this serial communication line can be human readable, this will allow a potential user to test the interface manually through a serial console program. The MCU should echo back the characters that it receives, if the interface is intended to be manually tested.
- Software Platform and Peripheral Usage: Both the MCU and the Linux-box sometimes offer the same peripherals. The Linux peripheral might offer a seemingly quicker (read: easier) path for development, but the MCU provides a more customizable base at the cost of time taken up for development of the driver and any high-level interfaces. While C-programming is an option to write device interfaces on Linux, there are also bindings to the same hardware peripherals offered through a Python module. Python is generally a good option when there is little customization required and when there is a need to integrate other application based libraries that already have Python modules.
- Cost and Miniaturization: Adding a Linux module is probably going to be the most significant addition to your total cost. Additionally, it is also probably the part with the largest footprint. For these reasons, it might be worth exploring a custom design with a Cortex-A (and it's supporting peripherals) without the extraneous devices that the Linux module might have. That being said, moving to a custom design, comes at a much more significant NRE expense because of the complexity of the design.
- Power Consumption: If your application is going to be battery powered, you will fight a harder battle to save power with the mid mW average current consumption for Linux modules vs low mW to high uW for MCU's.
- Startup Time: The boot-up time for Linux is in the 10's of seconds as opposed to bare-metal software on MCU’s which is in the milliseconds or less.