Recently I was asked by a developer, who has done windows development for 10 years, how to get started with Embedded Linux. Embedded Linux covers a lot of ground and includes a broad range of components/skills to put together an entire system. Below are a few suggestions.
Do I have the right Mindset?
There are many different types of people; there are those who are who are a good fit for Linux, and those who are not. There are those who think Open Source Software (OSS) and Linux are the craziest thing they ever heard of, and those who think it’s a great idea. There are those who thrive on openness and collaboration, and those who feel threatened by it. A few specific aspects of this mindset are described below.
Much of your time as an embedded Linux developer is spent figuring stuff out (vs writing new code). Figuring out stuff is harder than writing new code (at least initially). It is similar to weeding the garden — often not something you are raring to do, but after you are finished, it feels really good. Much of the truly valuable work in life is like this. It initially appears kind of boring, but once you get started there are many interesting and rewarding aspects.
You have to like build systems and automation. Linux systems are complex. You can’t throw millions of lines of kernel and user space code together with a simple Makefile or a fancy IDE. Proficiency with command line tools is required. Builds must be clean and completely automated if you want to keep your sanity. Once you allow one manual step in the build, the floodgate has been opened, and these manual steps will start to accumulate at a frightening pace until you have an unmaintainable mess.
Because of the complexity, you have to be able to collaborate with others. This requires a generous mindset. How can I make this easy for someone else to pick up once I am gone? Most likely this someone will be you in a couple months or years when you have forgotten many of the project details. The same really applies to coding. Do I write my code to be clever, do I hack it together, or do I focus on making it maintainable and easily understand by others? Automation and simplicity reduce cognitive load, freeing up resources to think about the problems that actually need solved, and allow multiple people to work on a project without a lot of friction.
The flip side of this is humility. With a complex system like Linux, there will be a lot of things you don’t know, and some difficult problems to solve. There is no one “manual” for Linux where you can go look up an answer. So we rely on open source communities for help. There are many people willing to help, so the key is to have the wisdom to know where and when to ask for help, and then the humility to ask. In Linux communities (and OSS in general), you will be surrounded by developers who are much smarter and more knowledgeable than you. At the very least, there will always be someone who knows something you don’t. If you don’t have the humility to acknowledge this and be willing to learn, then you will likely never be comfortable or effective working in an OSS environment.
This can all be a challenge for developers who are endowed with a healthy dose of NiH (Not Invented Here Syndrome). These are people who imagine themselves happiest writing and maintaining their own code, and who are not inclined to share it with others. Some imagine themselves as great software architects and coders (very few of us really are) who can make something better. They don’t want to spend long, arduous hours learning and debugging a complex system written by someone else. If this describes you, then perhaps Embedded Linux is not for you.
Are you a learner? Do you enjoy learning about new technology, tools, techniques, etc? Everything is always changing in the Linux world. New and compelling solutions are coming out every year. The real power of Linux and Open Source is knowing when and how to leverage these new technologies to solve real problems. If you are more comfortable doing things the way they have always been done, then perhaps you should just keep doing what you are doing.
The Problem of Abundance
Can you deal with a lot of choices? With Embedded Linux, there are many options for about every aspect of the system. There are multiple init systems. There are many programming languages. There are many libraries available for various tasks. There is no one, true way to implement Embedded Linux — you will have to make a lot of choices.
Ideas for Learning Embedded Linux
There are many books published on Linux, Embedded Linux, Yocto, etc. The Yocto documentation is pretty good. Videos from the Embedded Linux Conference are freely available. There are many blogs that cover Embedded Linux topics (such as this one). Subscribing to blog RSS feeds in feedly is a good way to keep up with recent developments.
The list of learning resources is endless, but perhaps the key thing to remember is there is no one place you can go to learn everything you need to know, like you might for a commercial RTOS. The good news is there is information available in many different formats, so you can choose what best fits your learning style.
Run Linux on your computers
One of the best ways to learn a lot about Linux is to simply use it for your personal and work computers. Ubuntu is very easy to get started with. If you go with something like Arch Linux, the install process will teach you a lot. I am very pleased with the combination of Arch Linux plus the XFCE desktop environment. This is a no-nonsense setup that does its job well, is very customizable, and stays out of my way. Any distribution will work — just pick something.
Embedded Linux aside, there is little to lose, and a lot to gain from running Linux. Linux systems are naturally much more immune to viruses, malware, and various other attacks than Windows. Linux systems are much more flexible than Apple computers. Some things might not look as pretty, or might take a little more work to set up. But the stability, flexibility, and consistency of a Linux system will save you time in the long run. As a software developer, most of our time is spent in an editor and browser — these work very well in Linux. Additionally, the terminal is a first class citizen in Linux rather than an afterthought.
Git is used in almost all open source projects these days, and enables new levels of collaboration. You need to know Git.
Do small projects with Raspberry PI, etc.
There are a number of embedded computer boards out there that are very well supported and quite cheap such as the Raspberry PI. Find something in your home that you want to automate — there’s nothing like a real project to motivate learning. With Linux, you learn best by doing. This will also give you an opportunity to learn application programming under Linux.
Build and install OpenEmbedded/Yocto or Buildroot
Take the previously discussed home automation project and create a custom build for the board using Yocto/OE or Buildroot. This will give you practice learning how to put together a custom embedded Linux distribution. Create recipes to package, and include your custom applications in the image at build time (instead of installing them afterwards).
These tools have a learning curve and may seem intimidating initially, but Linux is a complex system, and you need powerful tools.
Modify the Linux Kernel
Most embedded Linux projects require a small amount of kernel modification. This can be something as simple as changing the GPIO configuration on an ARM SOC (System on chip), or writing a driver for some custom hardware. There are many resources available for learning Linux kernel programming. Perhaps try creating a custom driver for your PC or embedded Linux board. This driver could do something trivial, like monitor several GPIOs, etc.
Modify and install U-boot
U-boot is a common bootloader for Embedded Linux systems (but not the only one). Locate the source code for your embedded board and learn how to build, modify, and install a custom version of U-boot.
Explore the many Application Programming Options
There are so many interesting application programming options with Linux. Of course you can stick with traditional C/C++. But today, there are many other languages and environments that may be better for various applications (Python, NodeJS, Golang, Qt/QML, etc).
Find something that is broken and fix it
There are many opportunities to improve open source code. Find something that does not work quite right, fix it, and get the changes accepted in the upstream project. This will provide valuable experience working with OSS communities. When working with complex systems like Linux, you will run into problems that are very hard to solve. Being comfortable with asking, and getting help from various OSS communities will be key to your success. Again, your mindset is key here. People who don’t have the right mindset will create fake names and email aliases to hide their true identity when asking questions. People with the right mindset are willing to be up front and admit there is something they don’t know.
One of the best ways to really learn something is to teach it or help others. Once you reach a certain level of proficiency, there are many opportunities in open source communities (stack overflow, mail lists, IRC, etc) to help others. In doing so, we usually receive back much more than we give.
Maintain Yocto or Buildroot support for an embedded board
There are many embedded Linux platforms out there that are not actively maintained or tested in Yocto or Buildroot. Get involved and help keep the platform current and working in the build system.
Set up a server in the cloud
It is very cheap (less than $10/mo) to set up a server in Amazon AWS, Digital Ocean, Linode, Vultr, or one of the many other cloud providers. Although this is technically not embedded Linux, the skills required are very similar. It will also open up interesting possibilities of creating systems that are a combination of Embedded Linux devices and cloud servers.
Publish an Open Source project on Github
Publishing an open source project is a good experience as it helps you learn to create something that is generally useful. For example, I wrote a little app to test serial ports and published it on Github. Over the past few years, other people have provided nice contributions to the application, making it much more useful, with little effort on my part. However, I had to spend a little more time up front making the app generally useful and documenting how to use it.
Embedded Linux brings a level of functionality to systems that is unmatched by anything else out there, thus its popularity. With this broad scope of functionality comes complexity. Linux has a learning curve, and using it successfully requires some amount of discipline and interaction with various OSS communities. The resources are endless — time and motivation are the only limitations. In life, the rewards are proportional to the effort put forth. If you are committed, working with Embedded Linux is very rewarding, and brings a new level of functionality to products.