Why IDEs are Wrong for Embedded Developers

I’ll admit there was a time when I developed code using Integrated Development Environments (IDEs). They make it very simple to jump in and start working on a new project or coding in a new language. However, I have come to find that using an IDE for embedded development is almost never the right choice for a professional developer. Let me explain why.

What’s wrong with IDEs?

My first problem with IDEs is that they make it too easy for a person to develop code without fully understanding what they are doing. Some people may see this is a good thing and argue that IDEs are wonderful tools for students and people who are trying to learn to program. This could not be farther from the truth.

A student who is serious about learning software development should achieve an in-depth understanding of project setup and the build process. They should learn the intricacies of a compiler. They should learn what an object file is and what a linker does. These are fundamentals that are very important to the end result (producing a quality product) — not something that should be stumbled upon accidentally. IDEs make it too easy to get by without knowing the fundamentals of embedded system development.

Another problem with IDEs is that each imposes a way of doing things that is unique to that specific IDE. For example, they all use different keyboard shortcuts to start a build or run tests. They all have a different way of configuring builds and specifying source/include directories. Almost all of them I’ve used are cumbersome, feature-lacking text editors. In general, they slow down the development process by making it difficult for a person to get used to one way of doing things. If a developer is writing C code for three different types of microcontrollers, why should they have to use three different development environments? Ideally, a developer should become an expert at a single system and use that for all of their work.

Who are they targeting?

The thing that boggles me the most about IDEs is that they do not seem to be built with their target user in mind. The primary user group for an IDE is software developers. But we’re both familiar and comfortable with code. We live code, we breathe code, we think about code even when we don’t want to be thinking about it. So why do we need a visual, form-based system to help us configure a build environment? A simple config file would do. In fact, I think having to search around in menus to find a configuration setting is anti-productive and non-transparent.

Who is to blame?

This is a really important question. I don’t like to say it, but I think we (the developers) are partially responsible. If embedded device manufacturers were receiving a lot of requests for more high-quality command-line tools, we’d be seeing more available. If more embedded developers stopped using IDEs, we’d see manufacturers stop spending all their time trying to make them not suck and spending more time giving us things that we really need (better documentation, better compilers, etc.).

So what are IDEs good for?

I’ve done a lot of IDE bashing so far, but there two things that IDEs are good for:

Hobbyists – A hobbyist is someone who doesn’t want to spend their life becoming an expert developer, and they shouldn’t have to. They typically want a quick and dirty solution to help them solve some problem. IDEs can be a useful tool to facilitate this type of developer.

On-target Debugging – Interfacing with real-world stimuli can be very challenging. There are times when debugging on target is really the fastest way to get to the bottom of an issue. Unfortunately, most embedded device manufacturers do not offer a command-line debugging utility. This leaves us with the IDE as our only option for debugging on-target. I generally keep an IDE workspace file in my repository just for the random times where I may need to debug on target.

How should I be developing?

1. Use a full-featured text editor.

Use a tool that is specifically designed for efficiently writing code. Pick the one that you like best, one that has the features that are most important to you. There are a ton of them out there. Sublime Text 2 is my current editor of choice but Emacs, vim and Notepad++ are some other popular ones.

2. Customize it.

Once you find a good editor, customize it. Create keyboard shortcuts that make sense to you and speed up tasks that you do often.

3. Read your compiler’s documentation.

Learn how to use it from the command line and know it like the back of your hand. You’ll be surprised at how uncomplicated it really is. Experiment with changing compiler optimization levels, and familiarize yourself with the various output files that the build tools generate.

4. Find a good build tool.

Once you have a decent understanding of what the build process entails, find a build tool that is designed for building code. Again, there are a lot of them out there, so shop around, read reviews, pick one, and give it a try. I am a little biased towards Ceedling, but check out Wikipedia’s list of other tools. If you need help setting up the build process, check if the IDE you use generates a Makefile or console output while building; these can be a helpful resource.

5. Consider using Test-Driven Development.

The great thing about using an automated build environment is that it becomes very simple to use any other tool that has a command-line interface in your development process. For example, I highly recommend using Test Driven Development. Using a testing framework designed for your language greatly simplifies the task of unit testing. Unity and CMock are great unit testing tools for C, and they come bundled with Ceedling! These tools can be easily incorporated into your development process if you use an automated build system.

6. Run your code in continuous integration.

A continuous integration server is a system that monitors the code base (version control system) for changes and automatically builds the code and runs tests when it detects a change. Every software development team should be running their code in continuous integration because it gives the entire team instantaneous feedback of the ongoing state of the project.

Continuous integration can be done easily when the project is setup with an automated build system but is much more challenging to use with an IDE. If you are looking for a good continuous server, take a look at TeamCity.

3 Comments

I have come to discover that using an IDE for included growth is almost never the right option for an established designer.My first issue with IDEs is that they create it too possible for a individual to create value without completely knowing what they are doing.

Also, if you have several micros in your system (my last had 6 ARMs) because you want the subsystem abstraction, you need to manage the builds and source in a common manner. A make file can easily be setup to point to the right chunks of source code (including all of the common code for drivers, etc), and an easy copy/edit to create a new build. But an IDE forces you to either re-create the project from scratch, or (if you are lucky) edit an XML file.

Another issue is the IDE hides all of the compiler and linker options – you need to click thru bunches of tabs and menu selections.

Give me vim, gcc, a linker, loader, and a serial port. I have a CLI I have used on many projects, and it works great.

Another problem with IDEs when you use it to debug – they cannot handle interrupts (ISRs) worth a darn.

The only thing I find useful about an IDE is the JTAG support to set a breakpoint after a device gets inited, then look at the device registers. However, I have had IDEs lie because the register has different meanings, based on mode. Better just to create a CLI command to dump the register contents.