The STM Shell – pronounced stem shell because I like a good pun – is a minimalistic library that provides a customizable command line interface (CLI) to your STM32 projects.
Now, this library may be minimalistic, but it still requires you to do some work to add it to your projects. Boring work. Enough boring work, in fact, that I feel it necessary to start by selling you on the many features and benefits of STM Shell. So you know you’re not wasting time just to get some improved “printf” or logging mechanism. I apologize if I underestimate your wisdom and patience, I just don’t know who else will be reading this except my future self. Feel free to skip to the good stuff if you’re already convinced.
Let’s start with a good old meme to set the tone :
STM Shell adds an interactive command line interface to your STM32 firmware project. Through a UART or a USB port, you’ll be able to connect to your STM32 using a terminal emulator like PuTTY or TeraTerm and enter commands to a prompt as if there was a Linux-like operating system running on your microcontroller.
Here are some features and benefits of STM Shell :
Open source and free to use : this library is available on my GitHub under the terms of the GNU GPL version 3. If you’re planning on using it at work and you’re unsure whether or not you can, get in touch with me. You should also read my Legal page first.
Maturity : STM Shell has been used daily on real-life projects that I actually got paid for, since 2022. The reviews have been overwhelmingly positive and not just because I’m a scary dude. Another way to put it is that it solves more problems than it creates.
Performance : STM Shell has been designed from day one as a test and validation tool. If used correctly (which you’ll learn to if you keep reading) its impact on the execution of your application code is negligible. It does that by acting like a crude multi-tasking operating system which can be given lower priority than your application code.
Familiarity : STM Shell is a means, not an end, so you shouldn’t have to learn a new command line syntax to use it. The user experience is similar to that of a Linux shell. It even has “ls” and “cd” commands.
Flexibility : You can easily add as many commands to your project’s STM Shell as you need. Each command is just a C function that only needs to follow a few simple rules, and those rules have been packaged into macros for your convenience.
Arguments : Your custom commands can take command line arguments.
Organization : You can organize your custom commands into directories. Directories can be nested to any number of levels. Commands can be made callable from any directory or from one or several specific directories. This lets you organize your commands by context and reuse command names for different purposes in different contexts. I call this the pseudo-filesystem or PFS.
Logging : STM Shell provides a logging macro that outputs strings to the same UART as the shell, using the same low-impact DMA transmission method as the shell.
Segregation : STM Shell and the commands you write for it are kept separate from your application code. This is essential if you do not intend to release your products with a shell that could be a security vulnerability.
Last but not least, STM Shell is OS-independent. It was designed for bare-metal projects but also works within FreeRTOS projects. Although I haven’t tried it yet, it should also work on other embedded operating systems.
I’m hoping you’re sold because now comes the bitter part, the long list of what you’ll need to do to integrate STM Shell into your project and use it :
- Setting-up your STM32 project to meet STM Shell’s requirements
- Cloning the STM Shell repository into your project
- Taking care of project settings and version control
- Override a few functions of both my library and the ST HAL
- Learn to create your own shell commands and menus
I’m not going to lie, if all you’ve ever used is an Arduino or Python then a few of those steps require software development skills you may not have yet. It will give you plenty to Google, though, and in the end it’s nothing complicated. It’s just tedious. It’s up to you to decide if you’re a “delayed gratification” kind of person, or if you want to eat your cake first and then spend months debugging it with “printf”.
If this is giving you second thoughts, keep reading.
Perhaps you’re wondering why a microcontroller would need a command line interface. This sounds more like something for a PC or a server, not for a vacuum cleaner or a quadcopter. There are many reasons I can think of, so I can’t make a list, but I can instead bore you for a while longer with one of the predicaments I routinely find myself in that led me to create this library : integration.
Suppose you’re working on a new product. Eventually, the first prototype boards will land on your desk. Up until then, all you’ve had were calculations, simulations and perhaps a bit of code running on a proof-of-concept board or development kit that has almost nothing in common with the final product. You can’t just plug the power in, flash some code and hope for the best. That’s how the magic smoke gets released and prototypes go to prototype-heaven.
Even if you get lucky and don’t fry your board, there’s almost no chance your code will be perfect from the get go. There will be bugs and performance issues you’ll need to identify and address. And your employer may require you to prove that your code does what it’s specified to do, by writing and executing a test plan. I have yet to see a test plan that does not require dedicated test software. And no, “the BIST returns OK” doesn’t work in industry, except as a joke.
Debugging with your ST-LINK probe will only get you so far. Sure, you could create individual projects in CubeIDE to test individual parts of your board and your code, but that would be cumbersome. And what if your testing is done by a different team that doesn’t have access to your source code, or the means to flash a microcontroller ?
It would be far better if you could just have a way of calling test functions from a command line, wouldn’t it ?
You may also want to give your product a maintenance interface. Something that lets your customers know right way whether to send a broken product back to you for repair, or just save everyone time and chuck it into the trash.
Perhaps your product needs to calibrate itself after installation ? A one-time commissioning procedure that has to be performed by your client at their premises ? If it’s a choice between sending someone to do it or telling the client to enter a command, which do you think is cheapest and most practical for everyone involved ?
Like I’ve said, I could go on, but you probably get the point by now. If not, what are you still doing here ?
Let’s get a move on. Click here to start this quest.