What is a Real-Time Operating System (RTOS), and what does “real-time” mean anyway? What are the various kinds of state machines, and how to code them efficiently in C? What is object-oriented programming, and how does it work under the hood? How about event-driven programming?
Such questions, in one form or another, constantly appear in various discussion forums. But when you read the comments, you’ll find that all these fundamental concepts mean different things to different people. There seems to be no agreement about the terminology and consequently no common understanding of even the most basic concepts. Embedded software development, as a distinct discipline, appears to fall through the cracks, somewhere between EE (Electrical Engineering) and CS (Computer Science).
There is no shortage of books, articles, and courses, but they somehow don’t get to embedded developers. When I think about it, I haven’t learned embedded programming that way either. Instead, to truly understand a concept, I always found it necessary to see how it worked at a low level. That invariably helped me apply the concept more confidently and efficiently.
What worked for me might work for other fellow embedded developers as well. In 2013 I started a free video course on YouTube entitled “Modern Embedded Systems Programming”  with the intent to provide the “missing curriculum” of our discipline. Over the years the course gained viewers and subscribers, so now it seems to be the most popular embedded programming course on YouTube. Apparently, many developers liked the subject and my teaching approach.
From the beginning, my ultimate goal was to get to the modern programming concepts, such as event-driven programming, active objects (a.k.a. actors), hierarchical state machines, modeling, and automatic code generation. But to get there, I had to work backward and first explain all the intervening concepts, which took me “only” 8 years.
Now that I finally (almost) reached my original goal, I’d like to look back and present the whole course in the “Learn How to Program Embedded Systems” series. I see this as an opportunity to add new insights and observations. I also look forward to interesting comments and stimulating discussions.
In this first installment, I’d like to focus on the beginner section of the course consisting of lessons 1-6. Even if you already know all this, I’m sure that you will find something interesting there.
In lesson 1, you will see “how computers count.” This lesson introduces the hexadecimal system and the 2’s complement representation. Along the way, you will also see what the ARM Cortex-M machine instructions look like and peek inside the processor registers and the memory.
Lesson 1 – “How Computers Count”
In lesson 2, you learn how to change flow of control through your code. The lesson starts with running a simple linear program in the simulator and watching the execution of machine instructions, where the control flows top to bottom. Next, you will see how to change the control flow with a simple “while” loop and the “if” conditional in C. You then run the program and watch how the branch instructions modify the Program Counter (PC). You will also learn about the Application Program Status Register (APSR) and how it controls the execution of conditional jumps.
Lesson 2 – “How to Change the Flow of Control Through your Code?”
In lesson 3, you learn about variables and pointers in C. The lesson starts by moving the counter variable out of the main function to the top of the file. This makes the variable no longer local but instead allocated in memory, which causes a surprisingly significant change in the machine code. You learn about the load and store instructions and get an appreciation for the memory addresses. Next, you see how to represent the addresses in the C language through pointers. You will learn how to declare and initialize a pointer, obtain the address of a variable with the & operator, and de-reference a pointer with the * operator.
Lesson 3 – “Variables and Pointers”
Lesson 4 gets you to the point where you can interact with the external world, which will be blinking an LED on the TivaC board. The lesson starts with explaining how the LED connects to the microcontroller based on the schematics for the board. Next, you learn about the memory map and get the first look at the Data Sheet. You then experiment in the debugger, trying to access the registers of the GPIO block to control the LED. Still in the debugger, you configure the GPIO bits for digital output, and finally, you can turn all three colors on and off. You then code the same actions in C, which utilizes your knowledge of pointers from previous lesson 3.
Lesson 4 – “How a Computer Can Change Anything Outside, Like Blink an LED?”
In lesson 5, you learn how to improve the code from the previous lesson by using the C preprocessor and the volatile keyword. You see how macros can help you name hardware registers and how the vendor-provided header file conveniently defines all the registers. You notice that the header file defines the registers as “volatile” and you learn what that means. Specifically, to understand that “volatile” can be helpful also for the “normal” variables, you increase the compiler optimization level to “high” and see that your delay loops disappear. You fix the problem by making the loop counter “volatile.”
Lesson 5 – “Preprocessor and the “volatile” keyword in C”
Finally, lesson 6 shows how to set, clear, toggle, and shift individual bits utilizing the bit-wise operators in C. The lesson starts with explaining why you need to manipulate individual bits in the GPIOF DATA register to blink various colors of the composite LED on the Launchpad board. Next, you learn about bit-wise OR, bit-wise AND, bit-wise exclusive-OR, the one’s complement operator, the right bit-shift, and left bit-shift. You then step into the debugger and see all these operators translated into the ARM instructions: ORR, AND, EOR, MVN, LSR, and ASR. Next, you perform experiments with shifting signed and unsigned numbers. At the disassembly level, you learn about the LSR (logical shift) and ASR (arithmetic shift) instructions. Finally, you apply the knowledge to blink the red LED while keeping the blue LED turned on all the time.
Lesson 6 – “Bit-wise operators in C”
Since posting the early lessons of the video course, the “Stellaris LaunchPad” board was renamed to “TivaC LaunchPad,” and the LM4F microcontroller on the board was renamed to TivaC. The board referred to as EK-TM4C123GXL, is still available from most online distributors (e.g., DigiKey, Mouser, etc.) Also, the IAR EWARM toolchain underwent several upgrades, so the projects accompanying this video course [2, 3] had to be updated.
 The “Modern Embedded Systems Programming Course” playlist is sorted by most recent lessons first. You can go back as far as you need to get to the starting point corresponding to your level.
|Dr. Miro M. Samek is the creator of the open source QP real-time embedded frameworks and the freeware QM graphical model-based design tool. He is also the founder and CEO of Quantum Leaps — the provider of modern embedded software based on active objects and hierarchical state machines as well as tools for visual modeling, automatic code generation, and unit testing of deeply embedded software. Miro teaches the popular YouTube “Modern Embedded Systems Programming” video course on which this article series is based.|
- How containers improve the way we develop software
- How embedded software development has evolved over 20 years
- Programming embedded systems the easy way – with state machines
- Building Bare-Metal ARM Systems with GNU: Part 10 – Test Strategies
For more Embedded, subscribe to Embedded’s weekly email newsletter.