User Tools

Site Tools


Microcontroller development notes

:!: This page is under development.

Establishing a working microcontroller development setup involves two major areas:

  1. Software development environment
  2. Tools for programming the target

Your desire to use a given development host system for a given microcontroller can easily be derailed by gotchas in either of the areas above.

Software development environment

Development of programs that run on microcontrollers almost always happens on a desktop (or laptop computer). The programs are written and compiled/assembled/linked/what-have-you on the desktop (or laptop); then the result is loaded onto the microcontroller. The computer used to develop the program is called the host or the development system, the microcontroller is called the target processor, and the board on which the microcontroller is used is called the target system. The general term for compiling/assembling/linking/what-have-you-ing on one system but targeting another is cross-compiling or cross-platform-development.

The software tools installed on the host system (i.e., the host toolchain) that you'll use to prepare programs for a target system may include:

  • an assembler
  • tools to prepare binary code for loading onto the target
  • a programmer
  • a compiler (optional)
  • a linker (optional)
  • a simulator (optional)
  • a debugger (optional)

A compiler and linker will be required if you want to write your code in a high-level language. A simulator is useful for testing your code on the host system. A debugger can be used in conjunction with a simulator or with In-Circuit Emulation.

A programmer is used to load the binary code onto the target processor and is discussed more completely in a later section. A programmer isn't actually required if the target microcontroller has pre-installed on it a bootloader.

Language selection

You generally have a choice between assembly or some high-level language for the language used to develop microcontroller code. To develop in assembly, you must have an assembler for your host OS that produces output for the desired target processor. Similarly, to develop in a high level language for a given target, you need a compiler and linker for your host OS that produces output for the desired target.1)

While assembly offers the programmer the possibility of creating highly efficient code, the trend seems to be (especially for inexperienced developers) to start by programming in a high-level language. The defacto high-level language for microcontroller development is C. C compilers and linkers are available for a number of microcontroller families for a number of host operating systems. Sometimes, the C supported by a compiler will be a subset or superset of the language to simplify development for the target. JAL is a high-level language specifically developed to program PIC microcontrollers that apparently is popular in some circles.

Tools for programming the target

Once you have some executable code you have compiled/assembled/linked/what-have-you for the target system, you'll need to transfer it to the target system. This process is called programming the target, and the stuff you load onto the target is called firmware. Programming the target involves two tools: the hardware programmer, which is the go-between that electrically connects your host development system to the target microcontroller, and the software programmer, which lives in the development computer and talks to and controls the hardware programmer. 2)

If a suitable h/w programmer isn't available for your host computer, then you are screwed. Many commercial and DIY programmers use a serial bus on the host side—a solution that is obviously not workable if your computer lacks this antiquated port. Along similar lines, if a suitable s/w programmer for your OS isn't available for the chosen h/w programmer, you're screwed. So the list of dependencies is as follows:

  • The target microcontroller must be supported by the selected h/w programmer.
  • The selected h/w programmer must be supported by an available interface on the development system (e.g, serial bus or USB).
  • The selected h/w programmer must be supported by a s/w programmer available for the development system OS.
  • The selected s/w programmer must also support the target microcontroller.

Classic programmers

There are a few different “styles” of h/w programmers from the target's perspective. Classic microcontroller programmers require you to physically remove the microcontroller from the target system and place it into a socket on the programmer. You do a magic incantation on your host computer and the microcontroller gets programmed. Then you remove the microcontroller from the programmer and put it back into the target. This setup was the standard for many years, but clearly it has its disadvantages: the target microcontroller must be socketed on the target board (essentially making it impossible to work with SMD devices), and the repeated remove-replace cycles are not only tedious but can damage the target microcontroller.

In-System Programming

The problems associated with “classic” target device programming have lead to a second type of programmer “style” called In-System Programming (ISP). With an ISP programmer (pardon the redundancy), new firmware is loaded onto the target while the target microcontroller it is still in the circuit. In other words, the h/w programmer connects directly to the target board. This requires that the appropriate interface be designed into the target board (typically on the order of a six-pin header). ISP is often accomplished using an industry-standard communication protocol originally developed for testing assemblies called JTAG. So you'll see references to JTAG programmers—which are in fact ISP programmers.

:!: Do not confuse ISP with ICE (In-Circuit Emulation). ISP concerns itself with programming the target; ICE with debugging.



Other stuff

Having a software development environment and tools for programming the target is more-or-less the minimum you need to start developing working microcontroller projects. However there are a few other bits that can make the development process easier.


It's often useful to run your microcontroller code in an environment on the host that simulates the target system. The software tool that provides a simulated target environment is called a simulator. Simulators let you verify and/or debug code without making a round-trip target programming trip. If you do not have the needed hardware to perform ICE (In-Circuit Emulation), then simulation may be the only way to use a debugger with your code.

FIXME: Simulation vs. emulation.


A debugger is a software tool that you can attach to a computing process and use to pause program flow and inspect as well as in many cases adjust the program's and/or processor's state.

You can attach a debugger to a microcontroller process in one of a few ways:

  • Run it on a simulator on the host and attach a debugger to the simulated process.
  • Run it on a “virtual processor” on the host that connects to the target's socket with special hardware—and use a debugger on the host.
  • Run it on a special version of the target processor that makes the processor state information available to the host in a special h/w interface.
  • Run it on a stock version of the target processor that that makes the processor state information available to the host in a standard JTAG interface.

The last three above are all referred to as In-Circuit Emulation (ICE)—even though only one of them actually involve emulation.

See Linux microcontroller development options for a discussion of available FOSS tools for Linux.
There are most certainly other ways to get firmware to the target board (e.g., SD cards perhaps), but the programmer approach is far and away the most common.
microcontrollers/microcontroller_development_notes.txt · Last modified: 2013/08/23 21:34 by mithat