Introduction to Microcontrollers: 3 of 6

As you probably already know, this “Introduction to Microcontroller” series presents some of the basic concepts that must be mastered by anyone looking to become an embedded-system technologist. The concepts apply both to the hardware and software sides of system implementation.

In the first two parts of the series, we looked at microcontroller hardware. This time we look at programming languages and the software development environment.

Machine Language: The Only Language Your CPU Understands

The microcontroller's CPU reads program code from memory, one instruction at a time, decodes each instruction, and then executes it. All memory content—both program code and data—is in binary form: strings of 1s and 0s. Instructions are binary codes that tell the CPU what to do; while the data values are the binary (numerical) values that the CPU adds, subtracts, handles as address values, or otherwise operates on or processes in accordance with the instructions.

The left side of Figure 1 below shows a machine language instruction that loads a numerical value of 2 into Register A. (Registers are storage locations located within the CPU.)

The CPU reads these instruction codes from memory. The CPU reads instructions sequentially—from sequential memory addresses—unless instructed to jump. If we assume that instruction memory space starts at address 0000, for example, then following a reset the CPU will first get and execute the instruction stored at this address. It will then proceed (unless instructed otherwise) to get and execute instructions from addresses 0001, 0002, 0003, and so on. In other words, a program is a series of machine-language instructions describing the sequence of operations to be carried out.

Machine language is the only language the CPU understands. To drive the CPU, therefore, you need to supply it with a machine-language program.

Human programmers, however, find it very difficult to program using instructions composed of arbitrary sequences of 1s and 0s. Programmers needing to program at this low level therefore use assembly language instead—a language that uses meaningful text strings in place of arbitrary binary strings. The right side of Figure 1 below shows the assembly language instruction that corresponds to the machine language instruction on the left side.

Machine Language Instruction

0 1 0 1 0 0 0 1
0 0 0 0 0 0 1 0


Assembly Language

MOV A,#02

Figure 1: Assembly Language and Machine Language Representations for the Same Operation

While assembly language is clearly more workable (for humans) than machine language, it is still quite verbose, non-intuitive, and otherwise difficult to work with. Another problem is that machine language implementation is different on each CPU type. Since assembly code is closely mapped to machine code, assembly programmers would need to rewrite their code each time the CPU type is changed (the above example refers to Renesas's RL78 Family MCU). This need for continual rewriting would severely reduce the programmer's productivity and job satisfaction.

The C Programming Language: A Better Way to Program

Use of higher-level programming languages, such as C, resolves these problems. Programs written in C are very portable, since they can generally work on any CPU type without modification. They are also easier (for humans) to write and read, since they are more compact and use a much more descriptive set of English words and abbreviations. Figure 2 shows the difference between C code and assembly code for the same operation.

Figure 2: Identical Operation, Written in Assembly and C

Figure 2: Identical Operation, Written in Assembly and C

While humans find C code relatively easy to work with, CPUs cannot understand it. So it becomes necessary to convert the C code (source code) into machine code (object code) that the CPU can use. This conversion is carried out by a program called a compiler. The resulting object code must then be written into appropriate memory locations in order to enable execution by the CPU.

Because modern programs are quite complex, it is common practice to divide a programming job into multiple C programs. After compiling these programs into object files, it is necessary to link the objects together into a single machine-language program. This linkage operation is performed by another program, called a linker.

Debuggers: Discover and Correct Bugs

Since all humans are prone to error, the programs written by humans often contain bugs (defects or flaws). Consequently, humans have also created other programs, called debuggers, which can help discover and correct these bugs. Various types of debuggers are available, as follows.

An In-Circuit Emulator (ICE) is a dedicated evaluation chip that is mounted in place of the actual MCU, and used to help debug the code to prepare it for use with the actual MCU itself. Note that "in-circuit emulator" is a registered trademark of Intel Corporation. Renesas ICEs are called "full-spec emulators."
JTAG Emulator
Debugging circuitry built into the MCU itself. This type of debugging is less expensive than ICE debugging, since debugging can be carried out directly on the MCU. Renesas implementations are called "on-chip debugging emulators."
Debug Monitor
Debugging software that runs on the MCU together with the program being debugged, and communicates with a host computer where debugging work is carried out. Because the MCU must run the debug monitor in addition to the target program, functionality is more limited and execution speed is slower than with the ICE and JTAG approaches. The advantage, however, is that the costs are also much lower.

Integrated Development Environment

Engineers typically use numerous software tools when developing MCU software—including but not limited to the compilers, linkers, and debuggers described above. In previous days each of these tools was provided as a stand-alone program; and engineers ran the tools as needed from a command prompt or as a batch process. More recently, however, engineers can instead use an integrated development environment (IDE): a single package consisting of a full set of tools, all of which can be run from a common Renesas CS+.

CS+, for example, is an IDE for the RL78 Family of MCUs, designed to deliver stability and ease of use. Offering a broad range of easily operated functionalities, CS+ can greatly improve the efficiency of software development work.

* The product name of CubeSuite+, an integrated development environment from Renesas, has been changed to "CS+" from V3.00.00, which was released on October 1, 2014.

* This article was revised on March 30, 2015.

In part 4 of this series, we will look at the basics of MCU hardware control.

Module List

  1. MCU Basic Structure/Operation
  2. Peripheral Circuitry
  3. Programming Language/Software Development Environment
  4. Peripheral Circuitry Control
  5. Interrupt Processing
  6. Possible to start without starter kit! Development method using simulators