In C

Real life has intervened yet again and made this post much later than I had originally intended. Nevertheless, here I am again, and this time I’m going to look at some actual code! Whoop!

In Lab 2 I followed instructions for downloading a simple program to the micro on the LaunchPad demoboard. I didn’t mention anything about that code at the time, but now here it is in all its glory:

Lab2 main.png
Figure 1. The Lab 2 “main.c” code as seen in Code Composer Studio

The code shown in Figure 1 is written in a computer language called “C” (yup, just that – the letter C).

C is an extremely common programming language which has existed, in more or less the same form, since the late 1970s. There is a very informative history of the C language at this link. C is versatile, powerful and ubiquitous and is used for a huge number of different purposes, not just embedded programming.

My first exposure to C came in 2007 when I joined a work-based project based around an embedded microcontroller. Sadly the project was cancelled two years later, but in that time I managed to teach myself enough C to not be completely clueless when viewing code like the example shown in Figure 1. Disclaimer: this does not make me in any way a C expert, though! The book I used to learn C was “C How To Program” by P. J. and H. M. Deitel, which I highly recommend.

I was subsequently involved in two more embedded programming projects which were also cancelled before they came to fruition. Although this was frustrating, the positive take-away was that I also gained some exposure to the Eclipse Integrated Development Environment (on which TI’s CCS is based) and the processes of editing, linking, compiling and so on, which I’ll come to in due course. I suppose that in revisiting this subject, I’m really putting together a lot of fragments of knowledge from earlier projects into a more coherent whole.

Returning to the main.c example shown in Figure 1, if this example of code in its existing format was somehow downloaded into a microcontroller, it simply wouldn’t work – the micro wouldn’t have a clue what to do with it. That’s because C is an example of a “high-level” language i.e. a language which is easily understood by a human programmer. In order for the program to be usable by the micro it has to be translated into the micro’s own “machine level” language. This is essentially a large collections of ones and zeros, and is known as “executable code”. The process of creating executable code is shown in a somewhat simplified form in Figure 2.

Code creation process.jpg
Figure 2. The process of creating executable code (somewhat simplified)

Note that a similar process would be used for other microcontroller architectures such as the Microchip PIC architecture . The techniques learned for programming ARM-based micros are therefore somewhat “portable” to other architectures.

Every C program has a “main” component, more properly known as a “function” and the main function is where the programmer’s code is written. In Figure 1, main begins at line 7, with the code to make the LEDs flash sitting between lines 9 and 21. As well as the main function, a few other pieces of code are needed in order to produce a working executable file which can be downloaded to the micro. These include:

  • Library files. Certain pieces of code will typically be used over and over again in many projects. It therefore makes sense to store these pieces of code in locations where they can be copied (or “linked”) into a project as and when required, rather than constantly re-writing the same pieces of code. So referring to Figure 2, the compiler turns the C files into object code, but that code has gaps in it where the library functions need to be inserted. the linker understands this, and where those code libraries are kept, and inserts the necessary bits of code before turning the whole thing into the executable .out file.
  • The startup file. This code sets up various parts of the micro’s hardware and converts it from an inert piece of silicon into a machine with the potential to do useful things. I will examine the contents of the startup file in a later post.

So there you have it – a brief explanation of the code creation process as I understand it, hopefully without too many errors. Please be aware that I am writing this stuff to document my own learning in this field, not to provide an authoritative explanation of the subject to anyone else. If you see mistakes, please feel free to point them out.

Next time: a closer look at what’s going on in main.


PS: The title of this post – “In C” – is also the title of a piece of music by the minimalist composer Terry Riley. I participated in a performance of In C many years ago. Here’s one example from YouTube.