Embedded Command Line Interfaces and Why You Need Them

Throughout the development process, from hardware prototyping to manufacturing, the need to test code repeatedly arises. This is crucial for verifying functionality and performing system-level testing. 

However, relying on debuggers or restarting the device to trigger events can lead to delays during boot-up and initialization. Moreover, it assumes that manufacturers and non-developers possess the necessary knowledge and tools to navigate these complexities. Thus, it becomes essential for embedded systems to include a straightforward method for executing commands repeatedly through an accessible interface during development and manufacturing.

Enter the solution: a command-line interface (CLI). This tool empowers users to exercise various features and functions without requiring expertise in debugging or software intricacies. Testing can be efficiently conducted via the CLI using the most suitable communication interface for the scenario, such as UART, USB, RTT, or Bluetooth.

While custom CLI implementations are certainly an option, a wealth of open-source solutions is available that can often meet your needs with minimal modification. Before embarking on a project, it’s worth reviewing available open-source CLI solutions to find one that fits your requirements. Here, we outline the key features to consider when choosing or implementing a CLI for embedded systems.

Book a Call with Dojo Five Embedded Experts

Requirements

Based on experience with closed-source and internally developed CLIs, here are the key features to prioritize.

Must Haves

FeatureDescription
Open Source with Permissive LicenseThe solution should be easily redistributable, ideally under the MIT license.
Communication Interface AgnosticThe CLI should abstract input/output, supporting protocols such as UART, USB, and Bluetooth.
Bare Metal SupportThe CLI should not rely on any RTOS or other dependencies.
Basic Shell FunctionalityIncludes echoing input, backspace support, and help messages.
C or C++ ImplementationPreferably a small, lightweight library in C or C++, with minimal files.
Static Memory AllocationAvoids dynamic allocation, a best practice for embedded systems.

Nice to Have

FeatureDescription
Autocomplete and HistoryAllows easier interaction through tab completion and command history recall.
Parameter ValidationEnsures correct command arguments, improving usability.
Multiple Instances SupportEnables serving multiple CLIs over different interfaces or protocols.
Built-in HelpNative support for printing help messages and available commands.
Runtime Command RegistrationCommands can be registered at runtime, enabling dynamic updates.

Additional Considerations

Security Considerations

Securing embedded CLIs is crucial, especially in production environments. Best practices include implementing user authentication, encrypting communication interfaces, and restricting access to sensitive commands. For example, you can secure CLI access via password protection or encryption keys, ensuring only authorized users can interact with the system. A CLI secured with a password protects the system from unauthorized tampering during manufacturing or field use.

Performance Impact

When integrating a CLI into resource-constrained embedded systems, large command sets and strings, for instance, can increase the footprint and slow down system response times. Reducing string sizes by using a more compact and manual format can help mitigate this. Keeping the CLI lightweight and trimming unnecessary features will also minimize the impact on system resources. Another approach is to have separate applications for manufacturing and production. The manufacturing application has CLI, while the production application does not have access to the CLI.

Tip: Slimming down shell commands and minimizing string processing overhead will help keep your system responsive.

Interchangeable CLI Output Formats

A flexible CLI should support both human-readable and machine-readable formats, making it suitable for automated testing and interaction. This feature lets you toggle between output formats depending on the situation. For example, configuring the CLI to output structured data such as JSON or XML for machines while retaining plain text for human operators.

USB-CDC Support Example

A practical example would be adding USB-CDC support to your system, enabling two separate USB-CDC classes for different CLI instances: one for human operators and one for automated systems. This setup allows different users or processes to interact with the CLI simultaneously over the same hardware interface.

Hardware-Enabled CLI

In some systems, you can control when the CLI is available. For instance, external hardware could be used to determine whether the CLI is enabled at boot. If the hardware (such as a specific jumper) is absent, the CLI module would never load. This method ensures that the CLI isn’t exposed unnecessarily during operation, adding another layer of security.

Binary Protocols as an Alternative

In some cases, the full functionality of a CLI may not be necessary, or the nature of the deployment might not permit its use. A binary protocol could be a viable alternative for applications that only need basic interaction with the device (e.g., for simple commands or status updates). This reduces the code size and execution overhead while still allowing communication.

Reduced Functionality CLI

Sometimes, a lightweight, reduced functionality CLI is preferable. For example, a CLI that only exposes essential commands and omits advanced features (such as autocomplete and history) might be appropriate for a system with strict resource constraints.

Multiple CLI Instances

Some applications may require multiple CLIs or separate instances of a CLI. For example, you may need one CLI for handling RX and TX over different protocols, or need to create a distinction between userland and kernel interactions. In such cases, a system with support for multiple shells or CLI instances, each managing its state, would be beneficial.

By considering these additional aspects, you can create a flexible and powerful CLI that suits both your development needs and deployment scenarios, ensuring that testing, manufacturing, and troubleshooting are smooth and efficient.

Open-Source CLI Library Example

Based on the analysis above, our team found an open-source CLI library called embedded-cli. Check out the embedded-cli GitHub repository. It ticks every box except for parameter validation, but that was only a “nice to have” feature. We even discovered some additional features while integrating it into a template project. There is a hook function pointer that can be set up to be called whenever a command is about to be executed by the CLI library. It lets you print out the command and its arguments. What a great feature for debugging and logging!

Below is a table comparing the size of a project built before and after adding the CLI.

filenametextdatabssdechex
with_cli.elf40000664525209318416c00
without_cli.elf36048664509688768015680

Some of that will be the FreeRTOS task that was added to interface with the CLI library. Some optimization could be done to trim buffers and the task’s stack size, but ultimately, the increase of the binary size is worth the benefits, and if the CLI is not needed in production, it can be easily removed. The Funbiscuit’s embedded-cli project includes everything we were looking for and should make a great addition to our projects.

Why Use a CLI?

Initial Development

In the initial phase of an embedded project, it often starts with driver development. Developers can verify the implementation of the drivers by interacting with the hardware using the CLI.

Board Bring-up

There will be multiple revisions of boards throughout an embedded project. The firmware team can provide the hardware team with a set of CLIs to run through for verifying the functionality of a new board. By following this procedure, the hardware team can have higher confidence before distributing a new board to other departments for development.

Testing on Manufacturing Line

The same set of CLIs can also be used on the manufacturing line to verify new boards and capture board defects as early as possible. The testers on the manufacturing line can test various features and functions without using debuggers or deep software knowledge.

Automated Testing

By integrating an embedded project with Continuous Integration (CI) pipelines, the CLIs can be scripted and run automatically whenever submitting code changes to the source control platform. This makes sure that the new changes, such as updating calibration parameters, do not violate the software requirements.

Board Configuration

If a key-value store (KVS) exists in an embedded application, the end-of-line tester can use the CLI to interact with the KVS and configure new boards before shipping them to the customers. Developers can also use it to configure a board for developing certain features or reproducing a bug that is only observed in certain configurations.

Conclusion

Due to the precious flash space and security concerns, there is a debate about adding a CLI to an embedded application. With the benefits that it brings to facilitate the development and deployment of an embedded application, it is worth the effort to add a CLI.

DojoFive brings modern tools, techniques, and best practices from web and mobile development environments, paired with leading-edge innovations in firmware, to our customers for building successful products. We have talented engineers on hand ready to help you with all aspects of your EmbedOps journey. Bring us your interesting firmware problems that need solving – we are always happy to help out.

Discover why Dojo Five EmbedOps is the embedded enterprise choice for build tool and test management.

Sign up to receive a free account to the EmbedOps platform and start building with confidence..

  • Connect a repo
  • Use Dev Containers with your Continuous Integration (CI) provider
  • Analyze memory usage
  • Integrate and visualize static analysis results
  • Perform Hardware-in-the-Loop (HIL) tests
  • Install the Command Line Interface for a developer-friendly experience

Subscribe to our Monthly Newsletter

Subscribe to our monthly newsletter for development insights delivered straight to your inbox.

Interested in learning more?

Best-in-class embedded firmware content, resources and best practices

Laptop with some code on screen

I want to write my first embedded program. Where do I start?

The boom in the Internet of Things (IoT) commercial devices and hobbyist platforms like the Raspberry Pi and Arduino have created a lot of options, offering inexpensive platforms with easy to use development tools for creating embedded projects. You have a lot of options to choose from. An embedded development platform is typically a microcontroller chip mounted on a circuit board designed to show off its features. There are typically two types out there: there are inexpensive versions, sometimes called

Read More »
Medical device monitoring vitals

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part 1

IEC-62304 Software Lifecycle requires a lot of self-reflection to scrutinize and document your development processes. There is an endless pursuit of perfection when it comes to heavily regulated industries. How can you guarantee something will have zero defects? That’s a pretty hefty task. The regulatory approach for the medical device industry is process control. The concept essentially states that if you document how every step must be completed, and provide checks to show every step has been completed properly, you

Read More »
Operating room filled with medical devices

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part II

Part I provides some background to IEC-62304. Part II provides a slightly more in-depth look at some of the specifics. The IEC 62304 Medical Device Software – Software Lifecycle Processes looks into your development processes for creating and maintaining your software. The standard is available for purchase here. So what activities does the standard look at? Here are some of the major topics. For any given topic, there will be a lot more specifics. This will look at a few

Read More »